如果网页加载错误,我可以通过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
对象的一部分返回以及状态似乎太臭了。是否存在处理此方案的既定模式?
答案 0 :(得分:14)
控制器操作:
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错误订阅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);
}
});
答案 1 :(得分:0)
创建HandleErrorAttribute的重写版本(JsonHandleErrorAttribute?)并在json操作上添加[JsonHandleError]。
中的AjaxAuthorizeAttribute