我对异常处理的一些问题在MVC 4处理Web API异常在MVC与处置
我已经实现HandleErrorAttribute
和派生新的属性来定制。它的工作非常好。但我不想每次都重定向用户自定义错误页面。
我在动作中遇到的一些错误,从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);
}
}
重写方法od并且不使用base.xx? – Rob 2013-03-08 13:24:39
抱歉,我无法理解您提到的内容。 – 2013-03-08 13:29:25
我假设你有这样的事情:'public override onException',确保你没有'base.onException(context);' – Rob 2013-03-08 13:31:47