2014-07-24 114 views
7

我正在寫一個ASP.NET MVC應用程序,我遇到了以下問題。我想製作帶有關於錯誤的詳細信息的自定義錯誤頁面(比如錯誤消息或者什麼控制器導致錯誤),但是我不能在HandleErrorInfo對象的視圖上提供模型。如何爲對象提供HandleErrorInfo模型?

起初我配置了Web.config文件處理自定義錯誤:

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

然後創建錯誤控制來管理錯誤觀點:

public class ErrorController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View("Error"); 
    } 

    public ViewResult NotFound() 
    { 
     Response.StatusCode = 404; 
     return View("NotFound"); 
    } 
} 

而且在查看我加型號:

@model System.Web.Mvc.HandleErrorInfo 

但是模型每次都是空的,我不知道如何傳遞正確具有錯誤細節的對象以及該對象應被創建的位置。你可以幫我嗎?這樣做甚至有可能嗎?

回答

12

所以你在這裏處理兩個不同的'層'。 <customErrors>是主要的ASP.NET框架的一部分。然後HandleError是MVC框架的一部分。當您使用<customErrors> ASP.NET不知道如何將異常信息傳遞到視圖中時,它只會將您加載/重定向到錯誤頁面。

爲了使視圖正常工作,您需要將所有內容都保存在MVC生態系統中。所以你需要使用HandleErrorAttribute,或者一個變量。 You can see in the source code of the attribute它會嘗試檢測何時發生未處理的異常,並且如果啓用自定義錯誤,則會啓動一個新的ViewResult,其中HandleErrorInfo的實例在其中包含異常信息。

需要注意的是,在默認的MVC項目中,HandleErrorAttribute作爲App_Start/FilterConfig.cs文件中的全局過濾器應用。

+0

謝謝,現在一切工作正常。 –

+0

非常有用,我所缺少的是過濾器,出於某種原因,我評論說。謝謝! – Alex

+1

我與@Roman具有相同的設置,但我仍然面臨在錯誤視圖中爲空的HandleErrorInfo。我已經註冊了Filter,並且在控制器上也有[HandleError]。有人可以拋出一些光。 –

1

這並沒有爲我工作,但啓發我發現我的Global.asax.Application_Start()沒有註冊FilterConfig類,像這樣:

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 

這一點,再加史蒂芬五世的回答解決了我的空模型的問題。

5

我找到了另一種方法。發送錯誤模型以從控制器查看。

1. Global.asax中

protected void Application_Error(object sender, EventArgs e) 
{ 
    var httpContext = ((MvcApplication)sender).Context; 
    var currentController = " "; 
    var currentAction = " "; 
    var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext)); 

    if (currentRouteData != null) 
    { 
     if (currentRouteData.Values["controller"] != null && !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString())) 
     { 
      currentController = currentRouteData.Values["controller"].ToString(); 
     } 

     if (currentRouteData.Values["action"] != null && !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString())) 
     { 
      currentAction = currentRouteData.Values["action"].ToString(); 
     } 
    } 

    var ex = Server.GetLastError(); 
    //var controller = new ErrorController(); 
    var routeData = new RouteData(); 
    var action = "GenericError"; 

    if (ex is HttpException) 
    { 
     var httpEx = ex as HttpException; 

     switch (httpEx.GetHttpCode()) 
     { 
      case 404: 
       action = "NotFound"; 
       break; 

      // others if any 
     } 
    } 

    httpContext.ClearError(); 
    httpContext.Response.Clear(); 
    httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500; 
    httpContext.Response.TrySkipIisCustomErrors = true; 

    routeData.Values["controller"] = "Error"; 
    routeData.Values["action"] = action; 
    routeData.Values["exception"] = new HandleErrorInfo(ex, currentController, currentAction); 

    IController errormanagerController = new ErrorController(); 
    HttpContextWrapper wrapper = new HttpContextWrapper(httpContext); 
    var rc = new RequestContext(wrapper, routeData); 
    errormanagerController.Execute(rc); 
} 

2.錯誤控制器:

public class ErrorController : Controller 
{ 
    // 
    // GET: /Error/ 

    public ActionResult Index() 
    { 
     return RedirectToAction("GenericError", new HandleErrorInfo(new HttpException(403, "Dont allow access the error pages"), "ErrorController", "Index")); 
    } 

    public ViewResult GenericError(HandleErrorInfo exception) 
    {    
     return View("Error", exception); 
    } 

    public ViewResult NotFound(HandleErrorInfo exception) 
    {   
     ViewBag.Title = "Page Not Found"; 
     return View("Error", exception); 
    }   
} 

3.查看/共享/ Error.cshtml:

@model System.Web.Mvc.HandleErrorInfo 
@{ 
    ViewBag.Title = ViewBag.Title ?? "Internal Server Error"; 
} 
<div class="list-header clearfix"> 
    <span>Error : @ViewBag.Title</span> 
</div> 
<div class="list-sfs-holder"> 
    <div class="alert alert-error"> 
     An unexpected error has occurred. Please contact the system administrator. 
    </div> 
    @if (Model != null && HttpContext.Current.IsDebuggingEnabled) 
    { 
     <div> 
      <p> 
       <b>Exception:</b> @Model.Exception.Message<br /> 
       <b>Controller:</b> @Model.ControllerName<br /> 
       <b>Action:</b> @Model.ActionName 
      </p> 
      <div style="overflow: scroll"> 
       <pre> 
        @Model.Exception.StackTrace 
       </pre> 
      </div> 
     </div> 
    } 
</div> 

4.網頁。配置:

<system.web> 
    <customErrors mode="Off" /> 
</system.web> 

學分:https://thatsimpleidea.wordpress.com/2013/10/28/mvc-error-page-implementation/#comment-166

相關問題