3

PartialView を返すアクションがあります。

[ChildActionOnly]
public ActionResult TabInfo(int id, string tab)
{

    ViewBag.Jobid = id;
    ViewBag.Tab = tab;

    var viewModel = _viewModelManager.GetViewModel(tab, id);

    return 
        PartialView(string.Format("~/Views/{0}/Index.cshtml", tab), viewModel);

}

_viewModelManagerDictionary からビューを返します。ユーザーが存在しないタブを要求すると、KeyNotFound例外がスローされますが、私の見解では、次の例外が発生します。

Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'

@using MyApplication.UI.Helpers.Html
@model MyApplication.UI.Models.MyJobModel

@{
    ViewBag.Title = "Details";
}

<p>@Model.Blah</p>

...

*@ HttpException occurs here -- renders default error view *@
@Html.Action("TabInfo", new { id = ViewBag.Jobid, tab = ViewBag.Tab }) 

MSによると…

子アクション自体で例外が発生した場合、子アクション メソッドの HandleErrorAttribute 属性は無視されます。したがって、子アクションは独自の例外を処理する必要があります。子アクションに AuthorizeAttribute 属性が適用されている場合、属性が実行され、HTTP Unauthorized 401 ステータス コードが返されます。

子アクションのリダイレクトがサポートされていないため、これ[HandleError(ExceptionType = typeof(KeyNotFoundException), View="myError")]を使用できず、try/catch を使用してリダイレクトすることもできません。

子アクションの例外を処理する最良の方法は何ですか?

結論: 例外を処理してカスタム エラー ページを返したい。

4

3 に答える 3

3
  1. メソッドで例外がスローされた場合GetViewModel、return ステートメントは処理されません。実際にはApplication_Error、global.asax で終了する catch ステートメントがないためです (もちろん、ある場合)。

  2. ContainsKeyチェックを行う必要があるのは正しいです。それが false の場合は、エラー ページを返します。

  3. ContainsKey結果を変数に入れるだけAssertで、その変数は真ですか? viewModelまたは、変数をチェックして、false のAssert場合は、エラー ビュー名が実際に.ContainsKeyviewModel

Atry catchは、一般的な用語としてはあまり良い方法ではありません。回避できる場合は、追加のロジックを使用して例外の発生を防ぐ必要があります (ContainsKeyこの例のように)。例外は例外的な状況のためのものです:)。

于 2012-05-25T18:51:10.873 に答える
1

私の場合、子アクションに ModelState エラーを追加し (Exception のメッセージではなくカスタム メッセージを使用)、子アクションの部分ビューに ValidationSummary を配置します。親アクションの概要ではエラーが発生しないため、エラーが重複することはありません。もちろん、これでもページが表示されます。私の場合はまったく問題ありませんでした。

ただし、子アクションでこのようなことをしていないことを確認する必要がありますreturn PartialView(modelContainingPotentiallySensitiveInfo)。特定のシナリオを想像することはできませんが、通常、まったく異なるエラー ページに移動する理由は、そもそもエラーに関連するセキュリティ違反を防ぐためです。したがって、私の手法を使用する場合は、データベースからクエリしていない新しい空のモデルを作成して、部分ページに渡すようにしてください。

もちろん、PartialView の呼び出しで cshtml のエラーのような例外が発生した場合は、アクションを返してエラーを表示することはできません。したがって、これは完全な解決策ではありませんが、他の人にとっては十分かもしれません。

于 2012-11-14T18:09:15.800 に答える
0

他の誰かがこの質問に出くわした場合。

最終的に、try/catch ブロックを使用して KeyNotFound 例外をキャッチしました。エラーをログに記録し、ユーザーを ErrorView にリダイレクトします。エラー ビューでは、JavaScript を使用してユーザーを適切なビューにリダイレクトします。

[ChildActionOnly]
    public ActionResult TabInfo(int id, string tab, string jobno)
    {
        try
        {
            var viewModel = _viewModelManager.GetViewModel(tab, id);

            ViewBag.Jobid = id;
            ViewBag.Tab = tab;

            return PartialView(string.Format("~/Views/{0}/Index.cshtml", tab), viewModel);
        }
        catch (Exception ex)
        {
            return View("Error");
        }

    }

エラー表示

@model System.Web.Mvc.HandleErrorInfo

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <script type="text/javascript">
        window.location.href = '@Url.Content("~/400.htm")';
    </script>
</body>
</html>
于 2012-11-14T22:10:27.450 に答える