我對異常處理的一些問題在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