2011-11-15 27 views
40

Tôi đang kế thừa những HandleErrorAttribute trong ứng dụng MVC của tôi để tôi có thể ghi lại các lỗi:ASP.net MVC - Tuỳ chỉnh HandleError Lọc - Xác định Xem dựa trên Loại ngoại lệ

public class HandleAndLogErrorAttribute : HandleErrorAttribute 
{ 
    public override void OnException(ExceptionContext filterContext) 
    { 
     base.OnException(filterContext); 

     if(filterContext.Exception != null) 
     { 
      // log here 
     } 
    } 
} 

tôi thêm này như một bộ lọc toàn cầu :

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
    filters.Add(new HandleAndLogErrorAttribute()); 
} 

Có thể chỉ định chế độ xem tùy chỉnh cho các loại ngoại lệ cụ thể không? Ví dụ:

if(filterContext.Exception is DivideByZeroException) 
{ 
    // how do i specify that the view should be DivideByZero? 
} 

Trả lời

68
  1. Tạo một bộ lọc mới được thừa hưởng HandleErrorAttribute (hoặc thực hiện IExceptionFilter trực tiếp)
  2. đăng ký nó trong global.asax (bằng cách thay thế filters.Add(new HandleError());):

Dưới đây là một bộ lọc mà tôi đã tạo cố gắng tìm một chế độ xem theo mã trạng thái HTTP cụ thể:

public class MyErrorHandler : FilterAttribute, IExceptionFilter 
{ 
    public void OnException(ExceptionContext filterContext) 
    { 
     if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) 
      return; 

     var statusCode = (int) HttpStatusCode.InternalServerError; 
     if (filterContext.Exception is HttpException) 
     { 
      statusCode = filterContext.Exception.As<HttpException>().GetHttpCode(); 
     } 
     else if (filterContext.Exception is UnauthorizedAccessException) 
     { 
      //to prevent login prompt in IIS 
      // which will appear when returning 401. 
      statusCode = (int)HttpStatusCode.Forbidden; 
     } 
     _logger.Error("Uncaught exception", filterContext.Exception); 

     var result = CreateActionResult(filterContext, statusCode); 
     filterContext.Result = result; 

     // Prepare the response code. 
     filterContext.ExceptionHandled = true; 
     filterContext.HttpContext.Response.Clear(); 
     filterContext.HttpContext.Response.StatusCode = statusCode; 
     filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; 
    } 

    protected virtual ActionResult CreateActionResult(ExceptionContext filterContext, int statusCode) 
    { 
     var ctx = new ControllerContext(filterContext.RequestContext, filterContext.Controller); 
     var statusCodeName = ((HttpStatusCode) statusCode).ToString(); 

     var viewName = SelectFirstView(ctx, 
             "~/Views/Error/{0}.cshtml".FormatWith(statusCodeName), 
             "~/Views/Error/General.cshtml", 
             statusCodeName, 
             "Error"); 

     var controllerName = (string) filterContext.RouteData.Values["controller"]; 
     var actionName = (string) filterContext.RouteData.Values["action"]; 
     var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); 
     var result = new ViewResult 
         { 
          ViewName = viewName, 
          ViewData = new ViewDataDictionary<HandleErrorInfo>(model), 
         }; 
     result.ViewBag.StatusCode = statusCode; 
     return result; 
    } 

    protected string SelectFirstView(ControllerContext ctx, params string[] viewNames) 
    { 
     return viewNames.First(view => ViewExists(ctx, view)); 
    } 

    protected bool ViewExists(ControllerContext ctx, string name) 
    { 
     var result = ViewEngines.Engines.FindView(ctx, name, null); 
     return result.View != null; 
    } 
} 
+0

Mã trạng thái HTTP nào thực hiện việc xử lý này? Tôi đã ấn tượng rằng 404 sẽ không bao giờ bị Bộ lọc Lỗi bắt gặp và bạn cần sử dụng để bẫy chúng. – Dismissile

+0

tất cả được tạo ra thông qua HttpException. – jgauffin

+0

Giải pháp hay - tôi đặc biệt thích giải pháp đó để giữ lại thông tin về Bộ điều khiển và Hành động vi phạm. Tx! – Jaans

Các vấn đề liên quan