在ASP.NET MVC是什么,我认为最能展现未处理的异常?(In ASP.NET MVC what

2019-09-01 14:15发布

我在我的web.config以下:

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

我有一个

 [HandleError]

在我的HomeController类的顶部。 为了测试,我创建并简单地抛出一个异常动作。 。 并重定向到我

 ErrorController/Index

方法,但是当它到达我的观点,其结合HandleErrorInfo我的模型为空,所以我莫名其妙地失去了参考错误。

我相信它有事情做与重定向,所以我想看看,如果我失去了一些东西错误迷路,如果任何人有意见,我可以有一个观点,显示堆栈跟踪和错误消息。

Answer 1:

我可以看到误解。 你想要做的MVC的事情, redirect到一个控制器的动作。

但是defaultRedirect本身就是一个Web Form约定,因此限制了。 您重定向到另一个控制器的那一刻,你将失去你HttpContext ,从而失去你HandleErrorInfo对象

你的[HandleError]属性需要View指导其错误消息。 通过你上面的例子去,我假设你有一个Views/Error的文件夹为您ErrorController ,并在其中你有一个Index视图。 如果你想你的过滤器上下文的发送HandleErrorInfo对象这一观点,

试试这个语法:

[HandleError(View="~/Views/Error/Index")]
Public class HomeController : Controller

但是,我们记录?!?!?

我怀疑你的意图不仅仅是显示错误堆栈给用户更多 。 事实上,我怀疑你有没有这样的打算都没有。 我怀疑你的真正目的是记录自己的错误(可能为db),并显示一些刺激性的消息,你的用户是什么。

我到目前为止已经解释的是“ 什么是最好的[办法]显示未处理的在我看来例外 ”。 在[HandleError]属性是好了点。

但是,当你要移动到下一个步骤(记录错误),你有几种选择:

1) 重写您的基本控制器的有关异常的方法 ; 创建自己的Controller从MVC控制器类继承,但覆盖在例外情况的方法。 这种方法可以与[的HandleError]属性一起使用

2) 创建一个自定义异常处理程序创建自己的异常处理程序是记录错误。 然后,您的异常处理程序可以调用选择的视图,或者可以结合工作[HandleError(order=2)] ,因为过滤器属性可以采取施加优先的顺序的参数。


尼廷张以芳问一个错误观点是什么样子。 该

@model System.Web.Mvc.HandleErrorInfo
<h2>Exception details</h2>
<p> Controller: @Model.ControllerName </p>
<p> Action: @Model.ActionName </p>
<p> Exception: @Model.Exception </p>


Answer 2:

我做类似的东西maxlego负责处理所有的错误(不只是那些在控制器与属性的HandleError发生)。

我MvcApplication类(在的global.asax.cs)有这样的:

public class MvcApplication : HttpApplication
{
    // usual stuff here...

    protected void Application_Error(object sender, EventArgs e)
    {
        Server.HandleError(((MvcApplication)sender).Context);
    }
}

上面的代码使用扩展方法从有用的东西我的MVC库。 有了这个地方,我不需要任何的错误处理的属性,配置的customErrors或自定义过滤器。 相反,扩展方法将记录错误的详细信息,然后调用适当的视图,或者:

  • 拒绝访问
  • 未找到
  • 内部服务器错误

扩展方法的代码,使这项工作是:

public static class HttpServerUtilityExtensions
{
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

    public static void HandleError(this HttpServerUtility server, HttpContext httpContext)
    {
        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 exception = server.GetLastError();
        Logger.ErrorException(exception.Message, exception);

        var controller = DependencyResolver.Current.GetService<ErrorController>();
        var routeData = new RouteData();
        var action = "InternalServerError";

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

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

                case 401:
                    action = "AccessDenied";
                    break;
            }
        }

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

        routeData.Values["controller"] = "Error";
        routeData.Values["action"] = action;

        controller.ViewData.Model = new HandleErrorInfo(exception, currentController, currentAction);
        ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
    }
}

请注意,上述使用NLOG用于记录错误的详细信息,但可以很容易地改变以支持别的东西。 此外,解决ErrorController此方法时,尊重您的IoC容器。



Answer 3:

我已经使用这个一小段代码向用户显示处理的错误页面。 无论页面不存在或出现了其他一些错误。

    void Application_Error(object sender, EventArgs e)
    {
        // this value can be fetched from config or depend on DEBUG smybol
        if (!handleErrors)
            return;

        var error = Server.GetLastError();
        var code = (error is HttpException) ? (error as HttpException).GetHttpCode() : 500;

        if (code == 404)
        {
            // do something if page was not found. log for instance
        }
        else
        {
            // collect request info and log exception
        }

        // pass exception to ErrorsController
        Request.RequestContext.RouteData.Values["ex"] = error;

        // execute controller action
        IController errorController = new ErrorsController();
        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), Request.RequestContext.RouteData));
    }

和错误控制器是这个样子。 如果您需要详细的例外,它是通过访问的RouteData

public class ErrorsController : Controller
{
    /// <summary>
    /// Page not found
    /// </summary>
    /// <returns></returns>
    public ActionResult Http404()
    {
        return View();
    }

    /// <summary>
    /// All other errors
    /// </summary>
    /// <param name="actionName"></param>
    protected override void HandleUnknownAction(string actionName)
    {
        // in case detailed exception is required.
        var ex = (Exception) RouteData.Values["ex"];
        return View();
    }
}

您可以为每个HTTP代码添加不同的看法。 刚刚实施的行动HTTP {}代码



文章来源: In ASP.NET MVC what is the best show unhandled exceptions in my view?