2012-11-28 45 views
4

我很努力去理解如何正確處理ASP.NET MVC4中的錯誤。舉個例子,我創建使用「互聯網應用」模板創建一個新MVC4項目,並更新了我的家庭控制器來測試一些錯誤情況:404,401和其他異常的ASP.NET MVC4錯誤處理

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     ViewBag.Message = "Hello"; 
     return View(); 
    } 

    public ActionResult About() 
    { 
     throw new HttpException(401, "Not Authorized"); 
    } 

    public ActionResult Contact() 
    { 
     throw new Exception("Oh no, some error occurred..."); 
    } 
} 

我在我的web.config文件中啓用的customErrors:

<customErrors mode="On"></customErrors> 

當我運行應用程序,然後單擊「聯繫人」,我看到了〜/查看/共享/ Error.cshtml視圖如預期,因爲我有註冊爲一個全球性的過濾器的HandleErrorAttribute

但是,當我點擊「關於」,我得到標準的ASP.NET黃色錯誤頁面,說「運行時錯誤」。 爲什麼這兩個例外的處理方式不同,如何使用HandleError屬性獲取HttpException的實例?


的customErrors配置

理想情況下,我想以下的自定義錯誤頁:

  • 自定義的404(未找到)頁面這是很好的和用戶友好的
  • 自定義401(未授權)頁面,通知用戶他們無權訪問(例如,在檢查模型中特定項目的權限後拋出)
  • 在所有其他情況下(代替標準的黃色ASP.NET頁面)使用的通用錯誤頁面。

我已經創建了一個新的「Error」控制器,其中包含以上每個場景的視圖。然後,我已經更新在web.config中的customErrors像這樣:

<customErrors mode="On" defaultRedirect="~/Error/Trouble"> 
    <error statusCode="404" redirect="~/Error/NotFound"></error> 
    <error statusCode="401" redirect="~/Error/NotAuthorized"></error> 
</customErrors> 

404頁工作正常,但我完全不拿到401頁。相反,當我嘗試訪問Home控制器上的About操作時,我看到〜/錯誤/故障視圖(指定爲defaultRedirect的那個視圖)。

爲什麼我的自定義401重定向頁面不工作?

回答

15

ASP.NET使用401的內部將用戶重定向到登錄頁面。無論你打算拋出401未授權,而是拋出403禁止。

+0

這是一個偉大的(並且非常簡單)解決方案,謝謝! 爲了讀者閱讀這個問題的其他人的興趣,這裏是另一個很好的評論,描述了401和403之間的區別:http://stackoverflow.com/a/6937030/1145963 –

8

如果你真的需要返回401而不是403,那麼你可以使用:

HttpContext.Current.Response.SuppressFormsAuthenticationRedirect = true 
+0

有趣的是,沒有意識到這一點!謝謝:) –

+0

.NET4.5具體,但解決了FormsAuthentication接管所有401的問題。 – Nicholi

4

我有一個類似的問題,我不能讓401錯誤到我的頁面,儘管變化web.config。

對於401,您可能會看到標準401未授權頁面,即使您已將401添加到web.config中的customerrors部分。我讀到使用IIS和Windows身份驗證時,檢查發生在ASP之前。NET甚至看到了請求,因此你會看到它是自己的401.

對於我的項目,我編輯了Global.asax文件,重定向到我爲401錯誤創建的路由,將用戶發送到「未經授權查看此內容」視圖。

在Global.asax:

void Application_EndRequest(object sender, System.EventArgs e) 
    { 
     // If the user is not authorised to see this page or access this function, send them to the error page. 
     if (Response.StatusCode == 401) 
     { 
      Response.ClearContent(); 
      Response.RedirectToRoute("ErrorHandler", (RouteTable.Routes["ErrorHandler"] as Route).Defaults); 
     } 
    } 

,並在Route.config:

 routes.MapRoute(
     "ErrorHandler", 
     "Error/{action}/{errMsg}", 
     new { controller = "Error", action = "Unauthorised", errMsg = UrlParameter.Optional } 
     ); 

,並在控制器:

public ViewResult Unauthorised() 
    { 
     //Response.StatusCode = 401; // Do not set this or else you get a redirect loop 
     return View(); 
    }