Asp.net-Mvc

ASP.NET MVC 使用者友好的 401 錯誤

  • November 5, 2009

我已經在 ASP.NET MVC 站點中實現了錯誤處理,就像這篇文章所建議的那樣

404錯誤一切正常。但是如何正確顯示401 錯誤的使用者友好螢幕?它們通常不會拋出可以在內部處理的異常,Application_Error()而是操作返回 HttpUnauthorizedResult。一種可能的方法是將以下程式碼添加到Application_EndRequest()方法的末尾

if (Context.Response.StatusCode == 401)
{
   throw new HttpException(401, "You are not authorised");
   // or UserFriendlyErrorRedirect(new HttpException(401, "You are not authorised")), witout exception
}

但是在Application_EndRequest()Context.Session == null 內部,errorController.Execute()由於無法使用預設的 TempDataProvider 而失敗。

 // Call target Controller and pass the routeData.
 IController errorController = new ErrorController();
 errorController.Execute(new RequestContext(    
      new HttpContextWrapper(Context), routeData)); // Additional information: The SessionStateTempDataProvider requires SessionState to be enabled.

那麼,您能否建議一些如何在 ASP.NET MVC 應用程序中“使用者友好地處理”401 的最佳實踐?

謝謝。

查看 HandleErrorAttribute。從它子類化或添加您自己的實現,它將處理您感興趣的所有狀態程式碼。您可以使其為每種錯誤類型返回一個單獨的錯誤視圖。

以下是如何創建句柄錯誤異常過濾器的想法。我已經扔掉了大部分東西,只專注於我們的必需品。絕對看看原始實現以添加參數檢查和其他重要的事情。

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

       Exception exception = filterContext.Exception;

       string viewName = string.Empty;
       object viewModel = null;
       int httpCode = new HttpException(null, exception).GetHttpCode();
       if (httpCode == 500)
       {
           viewName = "Error500View";
           viewModel = new Error500Model();
       }
       else if (httpCode == 404)
       {
           viewName = "Error404View";
           viewModel = new Error404Model();
       }
       else if (httpCode == 401)
       {
           viewName = "Error401View";
           viewModel = new Error401Model();
       }

       string controllerName = (string)filterContext.RouteData.Values["controller"];
       string actionName = (string)filterContext.RouteData.Values["action"];
       filterContext.Result = new ViewResult
       {
           ViewName = viewName,
           MasterName = Master,
           ViewData = viewModel,
           TempData = filterContext.Controller.TempData
       };
       filterContext.ExceptionHandled = true;
       filterContext.HttpContext.Response.Clear();
       filterContext.HttpContext.Response.StatusCode = httpCode;

       filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
   }
}

然後你用這個屬性“裝飾”你的控制器動作:

[HandleManyErrors]
public ActionResult DoSomethingBuggy ()
{
   // ...
}

引用自:https://stackoverflow.com/questions/1679881