2014-02-24 451 views
31

我們希望處理403錯誤,404錯誤,由於MySpecialDomainException而導致的所有錯誤,併爲所有其他錯誤(包括IIS配置中的錯誤!)提供默認錯誤頁面。所有的錯誤應該返回適​​當的剃刀視圖,這將是非常好的在視圖前面有一個ErrorControllerE.g.是這樣的:ASP.NET MVC 5錯誤處理

public class ErrorController : Controller 
{ 
    public ViewResult NotFound() { return View(); } 
    public ViewResult Forbidden() { return View(); } 
    public ViewResult Default() 
    { 
     var ex = ObtainExceptionFromSomewhere(); 
     if(ex is MySpecialDomainException) 
      return View("MySpecialDomainException", new ErrorModel { Exception = ex }); 

     return View("GeneralError", new ErrorModel { Exception = ex }); 
    } 
} 

目前你找到許多不同的方式做到這一點在WWW上,一些最有可能過時。在這些:

  • Controller.OnException()
  • 錯誤過濾
  • 的customErrors在web.config中元素
  • 在Global.asax中的Application_Error事件處理

Q1:什麼推薦的方式來滿足ASP.NET MVC 5的要求?

此外我們想要捕獲IIS主機中發生的錯誤。 Q2:爲了防止IIS必須處理任何404s我們想添加一個匹配所有可能的URL的默認路由 - 這是值得推薦的嗎?更好地註冊IIS 404'以及?

問題3:甚至有可能註冊一個返回控制器的IIS錯誤頁面,或者只有IIS能夠使用ASPX /靜態HTML嗎?

+0

我m好奇..當IIS配置不正確時,你會如何建議使用Razor頁面?如果IIS不工作,剃刀不會工作... –

+0

是的,可能它甚至不可能。也許我們必須解決靜態HTML @ IIS。所以可能最好是用ASP.NET MVC覆蓋所有可能的URL,以防止404冒泡到IIS ... –

+0

http://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET -MVC-methods-explaine –

回答

39

最好的方法是使用Global.Asax,因爲您可以管理所有類型的錯誤(Ajax調用/所有意想不到的錯誤)。與其他人你不能這樣做。

像這樣:處理錯誤延伸的HandleError屬性

protected void Application_Error() 
{ 
    HttpContext httpContext = HttpContext.Current; 
    if (httpContext != null) 
    { 
     RequestContext requestContext = ((MvcHandler)httpContext.CurrentHandler).RequestContext; 
     /* When the request is ajax the system can automatically handle a mistake with a JSON response. 
      Then overwrites the default response */ 
     if (requestContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      httpContext.Response.Clear(); 
      string controllerName = requestContext.RouteData.GetRequiredString("controller"); 
      IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory(); 
      IController controller = factory.CreateController(requestContext, controllerName); 
      ControllerContext controllerContext = new ControllerContext(requestContext, (ControllerBase)controller); 

      JsonResult jsonResult = new JsonResult 
      { 
       Data = new { success = false, serverError = "500" }, 
       JsonRequestBehavior = JsonRequestBehavior.AllowGet 
      }; 
      jsonResult.ExecuteResult(controllerContext); 
      httpContext.Response.End(); 
     } 
     else 
     { 
      httpContext.Response.Redirect("~/Error"); 
     } 
    } 
} 
+0

如何獲取錯誤代碼以便在ServerError =「500」或其他 –

+0

中以動態方式傳遞Application_Error是在您遇到意外異常時處理的代碼,所以這意味着默認情況下您的響應結果將始終爲500(內部服務器錯誤)。但是如果你想改變錯誤代碼,你可以在你的代碼中創建自定義的異常,並且在錯誤異常的基礎上,你可以設置你想要的錯誤代碼... – natnael88

+0

爲什麼我的響應結果總是500。哦,我想我想我錯過了一件事。只有在有任何異常情況下才會調用Application_Error,如果發生404錯誤,它將不會被調用。我認爲它更好地使用web.config的404錯誤 –

6

更好的辦法。 處理錯誤的屬性具有以下優點

  • 隨着HandleErrorAttribute我們克服了異常 處理更多的控制。 HandleError允許我們在不同的控制器和操作中輕鬆處理不同的控制器和操作,在Application_Error 中獲取此功能我們需要藉助開關循環。

  • 一旦你進入的Application_Error你出MVC,你會失去 和ControllerContext那麼我們不能做很多事情,會很容易 可能的的HandleError。

看到以下職位如何擴展錯誤處理屬性和優勢

Advantages of [HandleError] over Application_Error

http://maheshde.blogspot.com.au/2012/09/error-handing-with-mvc-using-custom.html

http://www.codeproject.com/Articles/731913/Exception-Handling-in-MVC

+0

感謝這個Mahesh!我已經在您的博客上留言(https://maheshde.blogspot.com.au/2012/09/error-handing-with-mvc-using-custom.html?showComment=1511493570513),因爲我想知道如何攔截500個錯誤,並在某些情況下重新打包爲404. – mattpm

38

沒有金色的解決方案,所有的應用程序。

您可以在web.config中使用httpErrors顯示友好的錯誤頁面。與customErrors不同,這是一個IIS級別的設置,它甚至會向您顯示一個友好的錯誤頁面,以查看不在ASP.NET中的錯誤。

對於錯誤日誌記錄,我會建議去同一個的HttpModule像ELMAH: https://code.google.com/p/elmah/

我寫了整個博客張貼關於這一點,在我解釋的錯誤處理方式的不同: http://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging

+1

從字面上看,第二段「您可以顯示......」直接回答了這個問題。相比之下,沒有鏈接列表。只有2個鏈接 - 第一個直接鏈接到ASP.NET中用於錯誤日誌記錄的常用工具的鏈接,第二個鏈接到冗長的博客文章,詳細闡述了這個主題,但是甚至比這裏提到的更多。包括這一點我沒有看到任何傷害。感謝您的馴服。 – dustinmoris