2016-02-13 55 views
1

我爲我的MVC5項目實現了一個自定義錯誤處理程序,如果它不是customErrors屬性,一切都會好起來的。我來解釋:當我在應用程序中得到一個錯誤,我抓住它無效的Application_Error內從Global.asax中是這樣的:如何在Web.Config中完全控制customErrors?

protected void Application_Error(object sender, EventArgs e) 
     { 
      var httpContext = ((HttpApplication)sender).Context; 
      ExecuteErrorController(httpContext, Server.GetLastError()); 
     } 

public static void ExecuteErrorController(HttpContext httpContext, Exception exception) 
     { 
      if (!exception.Message.Contains("NotFound") && !exception.Message.Contains("ServerError")) 
      { 
       var routeData = new RouteData(); 
       routeData.Values["area"] = "Administration"; 
       routeData.Values["controller"] = "Error"; 
       routeData.Values["action"] = "Insert"; 
       routeData.Values["exception"] = exception; 

       using (Controller controller = new ErrorController()) 
       { 
        ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData)); 
       } 
      } 
     } 

然後,我ErrorController裏面我做的:

 public ActionResult Insert(Exception exception) 
      { 
       ErrorSignal.FromCurrentContext().Raise(exception); 
       Server.ClearError(); 
       Response.Clear(); 

       switch (Tools.GetHttpCode(exception)) // (int)HttpStatusCode.NotFound; 
       { 
        case 400: 
         return RedirectToAction("BadRequest"); 
        case 401: 
         return RedirectToAction("Unauthorized"); 
        case 403: 
         return RedirectToAction("Forbidden"); 
        case 404: 
         return RedirectToAction("NotFound"); 
        case 500: 
         return RedirectToAction("ServerError"); 
        default: 
         return RedirectToAction("DefaultError"); 
       } 
      } 

    public ActionResult Unauthorized() 
      { 
       return View(); 
      } 
... 

所以第一次,一切都很完美 但是!!由於NotFound或ServerError頁面不在共享文件夾中,代碼會自行重複。這些頁面應該設置customErrors屬性,但事情是我根本不需要它。我終於得到這個錯誤:ERR_TOO_MANY_REDIRECTS因此。

我一整天都在閱讀以尋找任何有關該問題的答案,並且發現每個發佈其代碼的人都會採用和我一樣的模式,無論我嘗試了什麼,都沒有任何效果。

通知我絕望了,如果條件:如果

我也評論這兩條線(exception.Message.Contains( 「NOTFOUND」)& & exception.Message.Contains( 「SERVERERROR」)!) global.asax因爲我讀過的每一個地方都說,我們需要刪除它們才能完成。

//GlobalConfiguration.Configure(WebApiConfig.Register); 
//FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 

而且,因爲絕望如果,我得到了這樣的回答:

Runtime Error 

Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed. 

Details: To enable the details of this specific error message to be viewable on the local server machine, please create a <customErrors> tag within a "web.config" configuration file located in the root directory of the current web application. This <customErrors> tag should then have its "mode" attribute set to "RemoteOnly". To enable the details to be viewable on remote machines, please set "mode" to "Off". 


<!-- Web.Config Configuration File --> 

<configuration> 
    <system.web> 
     <customErrors mode="RemoteOnly"/> 
    </system.web> 
</configuration> 

我也試過Response.TrySkipIisCustomErrors = true;和它不工作!

那麼,我怎麼能完全騎自定義錯誤,並在我的項目中管理自己的錯誤處理程序?

+1

檢查此可能的答案:http://stackoverflow.com/questions/13905164/how-to-make-custom-error-pages-work-in-asp-net-mvc-4 – RoteS

+0

謝謝你RoteS。我閱讀每一個答案,我找到了真正的答案。我會在幾分鐘內分享它。 –

回答

1

好的,感謝RoteS的評論。我終於找到了我需要完成的事情!

我通過執行ErrorController的方式並不好。

using (Controller controller = new ErrorController()) 
       { 
        ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData)); 
       } 

我發現通過使用ServerTransfert來代替,我們可以獲得customErrors屬性。這是最終的解決方案(測試):

protected void Application_Error(object sender, EventArgs e) 
     { 
      // Response.TrySkipIisCustomErrors = true; I don't know if I will need it someday. 
      var httpContext = ((HttpApplication)sender).Context; 
      var exception = Server.GetLastError(); 

      ErrorSignal.FromCurrentContext().Raise(exception); 
      Server.ClearError(); 
      Response.Clear(); 
      string relativePath = "~/Administration/Error/{0}"; 
      switch (Tools.GetHttpCode(exception)) 
      { 
       case (int)HttpStatusCode.BadRequest: 
        Server.TransferRequest(string.Format(relativePath, "BadRequest")); 
        break; 
       case (int)HttpStatusCode.Unauthorized: 
        Server.TransferRequest(string.Format(relativePath, "Unauthorized")); 
        break; 
       case (int)HttpStatusCode.Forbidden: 
        Server.TransferRequest(string.Format(relativePath, "Forbidden")); 
        break; 
       case (int)HttpStatusCode.NotFound: 
        Server.TransferRequest(string.Format(relativePath, "NotFound")); 
        break; 
       case (int)HttpStatusCode.InternalServerError: 
        Server.TransferRequest(string.Format(relativePath, "ServerError")); 
        break; 
       default: 
        Server.TransferRequest(string.Format(relativePath, "DefaultError")); 
        break; 
      } 
     } 

感謝RoteS的評論,指出我在正確的方向。

大衛