如何为对象提供HandleErrorInfo模型?

Rom*_*ska 12 error-handling asp.net-mvc

我正在写一个ASP.NET MVC应用程序,我遇到了以下问题.我想制作自定义错误页面,其中包含有关错误的详细信息(例如错误消息或导致错误的控制器),但我无法使用HandleErrorInfo对象在视图上提供模型.

首先,我配置了Web.config文件来处理自定义错误:

<customErrors mode="On" defaultRedirect="~/Error">
  <error statusCode="404" redirect="~/Error/NotFound"/>
</customErrors>
Run Code Online (Sandbox Code Playgroud)

然后我创建了错误控制器来管理错误视图:

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

    public ViewResult NotFound()
    {
        Response.StatusCode = 404;
        return View("NotFound");
    }
}
Run Code Online (Sandbox Code Playgroud)

在View上我添加了模型类型:

@model System.Web.Mvc.HandleErrorInfo
Run Code Online (Sandbox Code Playgroud)

但是模型每次都是null,我不知道如何将带有错误详细信息的正确对象传递给视图以及应该在哪里创建此对象.你能帮助我吗?甚至可以这样做吗?

Ste*_*n V 15

所以你在这里处理两个不同的'层'.<customErrors>是主要的ASP.NET框架的一部分.然后HandleError是MVC框架的一部分.当您使用<customErrors>ASP.NET时不知道如何将异常信息传递到视图中,它只会加载/重定向到错误页面.

要使视图有效,您需要将所有内容保留在MVC生态系统中.所以你需要使用HandleErrorAttribute,或者变量.您可以在源代码中看到它在未处理的异常发生时尝试检测的属性,如果启用了自定义错误,则ViewResult使用HandleErrorInfo其中包含异常信息的实例旋转新的.

需要注意的是,在默认的MVC项目中,它HandleErrorAttribute被应用为App_Start/FilterConfig.cs文件内部的全局过滤器.


equ*_*man 10

我发现了另一种方式.发送错误模型以从控制器查看.

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);
}
Run Code Online (Sandbox Code Playgroud)

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);
    }        
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

4. web.config:

<system.web>
    <customErrors mode="Off" />
</system.web>
Run Code Online (Sandbox Code Playgroud)

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