来自Ajax的报告错误调用了MVC中的PartialView方法

如果是正常的页面加载错误,我可以通过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)结果或错误消息?

从ViewResult中明确地评估html并将其作为Json对象的一部分返回以及状态似乎太臭了.是否存在处理此方案的既定模式?

控制器动作:

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:
    // https://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错误订阅global error handler,这样我们就不必为所有AJAX请求重复此错误处理代码,但如果我们想要,我们可以重复它:

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

最后,我们向控制器操作发出一个AJAX请求,我们希望在这种情况下返回HTML部分:

$.ajax({
    url: 'whatever/trevor',
    success: function (html) {
        $container.html(html);
    }
});
相关文章
相关标签/搜索