在ASP.NET MVC中,我视图中最好的显示未处理的exception是什么?

我在web.config中有以下内容:

   

我有一个

  [HandleError] 

在我的HomeController类的顶部。 为了测试,我创建和操作只是抛出一个exception。 。 它重定向到我的

  ErrorController/Index 

方法,但当它到达我的视图绑定到HandleErrorInfo我的模型为null所以我不知何故失去了对错误的引用。

我确信它与错误在重定向中丢失有关,所以我想看看我是否遗漏了一些东西,如果有人有建议我可以有一个显示Stacktrace和错误消息的视图。

我可以看到误解。 您想要执行MVCredirect到控制器操作。

defaultRedirect本身就是一种Web Form约定,因而受到限制。 当您重定向到另一个控制器时,您将丢失HttpContext ,从而丢失HandleErrorInfo对象

您的[HandleError]属性需要View来指示其错误消息。 按照上面的例子,我假设您有一个ErrorControllerViews/Error文件夹,并且在其中有一个Index视图。 如果您希望Filter Context将HandleErrorInfo对象发送到该视图,

试试这个语法:

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

但是Logging呢?!?!?

我怀疑你的意图不仅仅是向用户显示错误堆栈。 事实上,我怀疑你根本没有这样的意图。 我怀疑你的真正目的是记录你的错误(可能是数据库)并向你的用户显示一些淡淡的消息。

到目前为止我所解释的是“ 在我看来,什么是最好的方式来展示未处理的例外 ”。 [HandleError]属性适用[HandleError]

但是当您想要进入下一步(记录错误)时,您有以下几种选择:

1) 覆盖基本控制器的On Exception方法 ; 创建自己的inheritance自MVC Controller类的Controller,但覆盖On Exception方法。 此方法可与[HandleError]属性一起使用

2) 创建自定义exception处理程序创建自己的exception处理程序,记录错误。 然后,您的exception处理程序可以调用View of choice或者可以与[HandleError(order=2)]一起使用,因为filter属性可以采用优先顺序的order参数。


Nitin Sawant询问错误视图的样子。 该

 @model System.Web.Mvc.HandleErrorInfo 

Exception details

Controller: @Model.ControllerName

Action: @Model.ActionName

Exception: @Model.Exception

我做了类似于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库中的有用东西的扩展方法。 有了这个,我不需要任何error handling属性,customErrors配置或自定义filter。 相反,扩展方法将记录错误详细信息,然后调用适当的视图,或者:

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

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

 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(); 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容器。

我已经使用这段小代码向用户显示处理错误页面。 是否找不到页面或发生了其他错误。

  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 { ///  /// Page not found ///  ///  public ActionResult Http404() { return View(); } ///  /// All other errors ///  ///  protected override void HandleUnknownAction(string actionName) { // in case detailed exception is required. var ex = (Exception) RouteData.Values["ex"]; return View(); } } 

您可以为每个http代码添加不同的视图。 只需实施行动Http {Code}