2011-02-03 130 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