如果是正常的页面加载错误,我可以通过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); } });