Asp.net-Mvc

ASP.NET MVC 4 - 異常處理不起作用

  • January 6, 2014

當我的 ASP.NET MVC 4 應用程序發生錯誤時,我想根據錯誤類型為使用者自定義一個視圖。例如,找不到頁面或發生異常(帶有一些關於異常的使用者友好的詳細資訊)。我已經在 StackOverflow 和其他線上資源上查看瞭如何執行此操作的其他範例,但沒有一個答案對我有用。

基礎的

$$ HandleError $$屬性在 VS2012 中似乎不適用於針對 .NET 4.5 的 MVC 4 應用程序。這是我在家庭控制器中的程式碼:

[HandleError]
public ActionResult Index()
{
   Response.TrySkipIisCustomErrors = true; //doesn't work with or without this
   throw new NullReferenceException("Uh oh, something broke.");
}

它只是拋出一個異常,我希望返回預設的 ~/Shared/Error.cshtml 視圖,因為

$$ HandleError $$屬性,但我得到的只是一個 HTTP 500 內部伺服器錯誤,表明該頁面無法顯示。我檢查了我的 web.config,不同的配置似乎表現得很奇怪。在該部分中,它目前包含:

<customErrors mode="On" />

(我已經嘗試添加 defaultRedirect 和 customErrors mode=“Off” 但這沒有任何效果……共享的錯誤視圖或我擁有的 CustomError 視圖都沒有被呈現。如果我將 customErrors 模式更改為關閉,然後我可以按預期看到異常詳細資訊,因此它正確地拋出了“哦,有些東西壞了”異常。

我還嘗試將 OnException 處理程序添加到 HomeController,雖然我可以調試並看到 OnException 事件正在引發,但它沒有任何區別:

protected override void OnException(ExceptionContext filterContext)
{
   base.OnException(filterContext);
   filterContext.ExceptionHandled = true;
   if (filterContext == null)
   {
       filterContext.Result = View("CustomError");
       return;
   }
   Exception e = filterContext.Exception;
   // TODO: Log the exception here
   ViewData["Exception"] = e; // pass the exception to the view
   filterContext.Result = View("CustomError");
}

我也試過改變

$$ HandleError $$指定一個視圖,但這似乎也沒有做任何事情:

[HandleError(View="CustomError")]

任何幫助將非常感激。如果您需要更多詳細資訊,請告訴我。

我似乎記得您必須從非本地 IP 地址(通常是另一台電腦)呼叫該頁面。而且它必須是基於 IIS 的伺服器,而不是內置的開發伺服器(所以是 IIS 或 IIS Express,但是您必須配置 IIS Express 以進行外部訪問,這很痛苦)。

您實際上可以調試它,您必須在調試電腦上配置本地伺服器以接受外部請求,然後從遠端伺服器呼叫本地伺服器。

我還繼續閱讀 SO 答案和各種部落格文章,試圖讓自定義錯誤頁面正常工作。以下是最終對我有用的方法。

第一步是使用 IIS Express 進行調試,而不是使用內置的 Cassini Web 伺服器來“保證”調試體驗將反映實時環境。

創建一個控制器來處理應用程序錯誤,並為您要處理的每個自定義錯誤添加一個操作。該操作應該執行任何日誌記錄、設置狀態程式碼並返回視圖。

public class ErrorsController : Controller
{
   // 404
   [HttpGet]
   public ActionResult NotFound()
   {
       Response.StatusCode = (int)HttpStatusCode.NotFound;
       return View();
   }

   // I also have test actions so that I can verify it's working in production.
   [HttpGet]
   public ActionResult Throw404()
   {
       throw new HttpException((int)HttpStatusCode.NotFound, "demo");
   }
}

配置customErrorsweb.config 中的部分以重定向到您的自定義錯誤操作。

 <system.web>
   <customErrors mode="RemoteOnly" defaultRedirect="Errors/InternalServerError">
     <error statusCode="400" redirect="Errors/BadRequest" />
     <error statusCode="403" redirect="Errors/Forbidden" />
     <error statusCode="404" redirect="Errors/NotFound" />
     <error statusCode="500" redirect="Errors/InternalServerError" />
   </customErrors>

在 web.config 中添加該httpErrors部分system.webServer並將 errorMode 設置為Detailed。為什麼這對我來說是個謎,但這是關鍵。

 <system.webServer>
   <httpErrors errorMode="Detailed" />

在定義的路由中添加一條包羅萬象的路由,以將 404 引導到自定義頁面。

           // catchall for 404s
       routes.MapRoute(
           "Error",
           "{*url}",
           new {controller = "Errors", action = "NotFound"});

您可能還想創建一個自定義HandleErrorAttribute並將其註冊為全域過濾器以記錄 500 錯誤。

這些步驟在開發(IIS Express)和生產(IIS7)環境中都適用於我。您需要進行更改customErrors mode="On"才能看到開發中的效果。

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