8

Error通常のページ読み込みエラーの場合は、ビューとHandleErrorInfoモデルを介して例外の詳細をユーザーに報告できます。

ajax結果エラーを予期している呼び出しの場合、Jsonエラーを明示的に処理し、クライアントに詳細を渡すことができます。

public JsonResult Whatever()
{
    try
    {
        DoSomething();
        return Json(new { status = "OK" });
    }
    catch (Exception e)
    {
        return Json(new { status = "Error", message = e.Message });
    }
}

だから、私の問題は、Ajax呼び出しから部分的なビューを返すアクションへのエラーの詳細を報告する方法がわかりません。

$.ajax({
    url: 'whatever/trevor',
    error: function (jqXHR, status, error) {
        alert('An error occured: ' + error);
    },
    success: function (html) {
        $container.html(html);
    }
});

これは、クライアントに役立たないHttpエラーコード(内部サーバーエラーなど)のみを報告します。成功したPartialView(html)結果またはエラーメッセージのいずれかを渡すための巧妙なトリックはありますか?

からhtmlを明示的に評価し、ステータスとともにオブジェクトViewResultの一部として返すのは臭すぎるようです。Jsonこのシナリオを処理するための確立されたパターンはありますか?

4

2 に答える 2

15

コントローラのアクション:

public ActionResult Foo()
{
    // Obviously DoSomething could throw but if we start 
    // trying and catching on every single thing that could throw
    // our controller actions will resemble some horrible plumbing code more
    // than what they normally should resemble: a.k.a being slim and focus on
    // what really matters which is fetch a model and pass to the view

    // Here you could return any type of view you like: JSON, HTML, XML, CSV, PDF, ...

    var model = DoSomething();
    return PartialView(model);
}

次に、アプリケーションのグローバルエラーハンドラーを定義します。

protected void Application_Error(object sender, EventArgs e)
{
    var exception = Server.GetLastError();
    var httpException = exception as HttpException;
    Response.Clear();
    Server.ClearError();

    if (new HttpRequestWrapper(Request).IsAjaxRequest())
    {
        // Some error occurred during the execution of the request and 
        // the client made an AJAX request so let's return the error
        // message as a JSON object but we could really return any JSON structure
        // we would like here

        Response.StatusCode = 500;
        Response.ContentType = "application/json";
        Response.Write(new JavaScriptSerializer().Serialize(new 
        { 
            errorMessage = exception.Message 
        }));
        return;
    }

    // Here we do standard error handling as shown in this answer:
    // http://stackoverflow.com/q/5229581/29407

    var routeData = new RouteData();
    routeData.Values["controller"] = "Errors";
    routeData.Values["action"] = "General";
    routeData.Values["exception"] = exception;
    Response.StatusCode = 500;
    if (httpException != null)
    {
        Response.StatusCode = httpException.GetHttpCode();
        switch (Response.StatusCode)
        {
            case 404:
                routeData.Values["action"] = "Http404";
                break;
            case 500:
                routeData.Values["action"] = "Http500";
                break;
        }
    }

    IController errorsController = new ErrorsController();
    var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
    errorsController.Execute(rc);
}

グローバルエラーハンドラで使用されるErrorsControllerは次のようになります。おそらく、404アクションと500アクションのカスタムビューを定義できます。

public class ErrorsController : Controller
{
    public ActionResult Http404()
    {
        return Content("Oops 404");
    }

    public ActionResult Http500()
    {
        return Content("500, something very bad happened");
    }
}

次に、すべてのAJAXエラーに対してグローバルエラーハンドラーをサブスクライブして、すべてのAJAXリクエストに対してこのエラー処理コードを繰り返す必要がないようにすることができますが、必要に応じて繰り返すことができます。

$('body').ajaxError(function (evt, jqXHR) {
    var error = $.parseJSON(jqXHR.responseText);
    alert('An error occured: ' + error.errorMessage);
});

そして最後に、この場合にHTMLパーシャルを返すことを期待するコントローラーアクションに対してAJAXリクエストを起動します。

$.ajax({
    url: 'whatever/trevor',
    success: function (html) {
        $container.html(html);
    }
});
于 2011-11-22T17:52:04.647 に答える
0

オーバーライドされたバージョンのHandleErrorAttribute(JsonHandleErrorAttribute?)を作成し、jsonアクションに[JsonHandleError]を追加します。

JsonResultを使用してasp.netmvc[handleerror][authorize]のAjaxAuthorizeAttributeを確認してください。

于 2011-11-22T23:13:16.347 に答える