【发布时间】:2013-02-24 01:18:39
【问题描述】:
我对 MVC 4 的异常处理有一些疑问。
我已经实现了HandleErrorAttribute 并派生了一个新属性来自定义。它真的很好用;但我不想每次都重定向用户自定义错误页面。
我在 Actions 中遇到的一些错误是从 Web API 抛出的,我想在当前页面向用户展示它们。 例如,如果用户想要创建一条记录,但 WebAPI 由于模型状态无效而引发异常,则异常详细信息会以友好的方式显示在创建视图中。
但HandleErrorAttribute默认重定向Error.cshtml。
我可以处理 Actions 中的所有异常,但我认为还有其他方法。
我也跟着http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc实现HandleErrorAttribute
public class CustomHandleErrorAttribute : HandleErrorAttribute {
private readonly ILogger _logger;
public CustomHandleErrorAttribute() {
_logger = new NLogger(typeof(CustomHandleErrorAttribute));
}
public override void OnException(ExceptionContext filterContext) {
if(filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) {
return;
}
if(new HttpException(null, filterContext.Exception).GetHttpCode() != 500) {
return;
}
if(!ExceptionType.IsInstanceOfType(filterContext.Exception)) {
return;
}
// if the request is AJAX return JSON else view.
if(filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest") {
filterContext.Result = new JsonResult {
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new {
error = true,
message = filterContext.Exception.Message
}
};
}
else {
var controllerName = (string)filterContext.RouteData.Values["controller"];
var actionName = (string)filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
filterContext.Result = new ViewResult {
ViewName = View,
MasterName = Master,
ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
TempData = filterContext.Controller.TempData
};
}
_logger.Error(filterContext.Exception.Message, filterContext.Exception);
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
我通过 HttpClient 和包装类进行了 Web API 调用。例如 Get 请求如下所示。
public async Task<BrandInfo> Create(BrandInfo entity) {
using(var apiResponse = await base.PostAsync(BaseUriTemplate, entity)) {
if(apiResponse.IsSuccess) {
return apiResponse.Model;
}
throw new HttpApiRequestException(
string.Format(HttpRequestErrorFormat, (int)apiResponse.Response.StatusCode, apiResponse.Response.ReasonPhrase),
apiResponse.Response.StatusCode, apiResponse.HttpError);
}
}
【问题讨论】:
-
重写方法不使用base.xx?
-
抱歉我没听懂你说的。
-
我假设你有这样的东西:
public override onException,确保你没有base.onException(context); -
哦,好的。我不记得基地。我还编辑了我的答案并分享了我的代码。
标签: asp.net-mvc error-handling asp.net-web-api