2011-02-03 101 views
5

我在MVC中的错误处理挣扎了几天。我仍然没有把握。 (我也看到了大部分问题在这里SO和GOOGLE上搜索,直到我的手指流血)在MVC中处理错误

我想要做什么:

  1. 使用标准[Authorize]属性
  2. 重定向的所有错误,以我的错误控制器(包括未经授权的)
  3. 在我的错误控制器中对每个HTTP错误执行一个操作。

我不想做的事:

  1. 放在我所有的控制器的[ErrorHandler](能不能我的基地控制器上使用)?
  2. 使用自定义的授权属性。

其实我可以做任何必要的事情(包括NOT列表),只要我#1-3工作。

我已经试过什么:

  1. 使用Application_Error
  2. 使用Controller.HandleUnknownAction
  3. 使用Controller.OnException
  4. 使用我控制器[ErrorHandler]
  5. 在web.config中
  6. 打开/关闭 CustomErrors

猜猜我需要这些或者其他的组合?

回答

2

您可以使用自定义过滤器,只需扩展ErrorHandlerAttribute并使其知道您的错误控制器。比它添加为一个全球性的过滤器内部Application_Start

GlobalFilters.Filters.Add(new CustomAErrorHandlerAttribute()); 
4

你也可以处理您Global.asax.cs,然后路线他们在不同的HTTP状态代码动态基地Application_Error所有的错误逻辑:

protected void Application_Error(object sender, EventArgs e) 
{ 
    var ex = Server.GetLastError().GetBaseException(); 

    var routeData = new RouteData(); 

    if (ex.GetType() == typeof(HttpException)) 
    { 
     var httpException = (HttpException)ex; 

     switch (httpException.GetHttpCode()) 
     { 
      case 401: 
       routeData.Values.Add("action", "NotAuthorized"); 
       break; 
      case 403: 
       routeData.Values.Add("action", "NotAuthorized"); 
       break; 
      case 404: 
       routeData.Values.Add("action", "PageNotFound"); 
       break; 
      default: 
       routeData.Values.Add("action", "GeneralError"); 
       break; 
     } 
    } 
    else 
    { 
     routeData.Values.Add("action", "GeneralError"); 
    } 

    routeData.Values.Add("controller", "Error"); 
    routeData.Values.Add("error", ex); 

    IController errorController = new ErrorController(); 
    errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); 
} 

看来401不会引发所需的HttpException所以你要手动处理,要符合逻辑:

protected void Application_EndRequest(object sender, EventArgs e) 
{ 
    if (Context.Response.StatusCode == 401) 
    { 
     throw new HttpException(401, "You are not authorised"); 
    } 
} 

是的,你的控制器继承你的基础控制器的属性。

+0

试过了。它不会被要求401.我不知道为什么。 – jgauffin 2011-02-03 12:02:17