leo*_*ora 18 c# asp.net-mvc unhandled-exception asp.net-mvc-4 asp.net-mvc-5
我在web.config中有以下内容:
<customErrors mode="On" defaultRedirect="Error">
<error statusCode="404" redirect="Error/NotFound" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)
我有一个
[HandleError]
Run Code Online (Sandbox Code Playgroud)
在我的HomeController类的顶部.为了测试,我创建了一个简单抛出异常的动作..它重定向到我的
ErrorController/Index
Run Code Online (Sandbox Code Playgroud)
方法,但当它到达我的视图绑定到HandleErrorInfo我的模型为null所以我不知何故失去了对错误的引用.
我确信它与错误在重定向中丢失有关,所以我想看看我是否遗漏了一些东西,如果有人有建议我可以有一个显示Stacktrace和错误消息的视图.
Dav*_*ich 24
我可以看到误解.你想做的MVC事情和redirect控制器动作.
但defaultRedirect它本身就是一种Web Form惯例,因而受到限制.当您重定向到另一个控制器时,您将失去您的HttpContext,从而丢失您的HandleErrorInfo对象
您的[HandleError]属性需要a View来指示其错误消息.按照上面的例子,我假设你有一个Views/Error文件夹ErrorController,你有一个Index视图.如果您希望过滤器上下文将HandleErrorInfo对象发送到该视图,
试试这个语法:
[HandleError(View="~/Views/Error/Index")]
Public class HomeController : Controller
Run Code Online (Sandbox Code Playgroud)
但是Logging呢?!?!?
我怀疑你的目的是更不仅仅是显示错误堆栈给用户.事实上,我怀疑你根本没有这样的意图.我怀疑你的真正目的是记录你的错误(可能是db)并向你的用户显示一些平淡的消息.
到目前为止我所解释的是" 在我看来,什么是最好的方式来展示未处理的例外 ".该[HandleError]属性对此有利.
但是当您想要进入下一步(记录错误)时,您有以下几种选择:
1)覆盖基本控制器的On Exception方法 ; 创建自己Controller继承自MVC Controller类但是覆盖On Exception方法.此方法可与[HandleError]属性一起使用
2)创建自定义异常处理程序创建自己的异常处理程序,记录错误.然后,您的异常处理程序可以调用View of choice或者可以一起使用,[HandleError(order=2)]因为过滤器属性可以使用优先级的order参数.
Nitin Sawant询问错误视图的样子.该
@model System.Web.Mvc.HandleErrorInfo
<h2>Exception details</h2>
<p> Controller: @Model.ControllerName </p>
<p> Action: @Model.ActionName </p>
<p> Exception: @Model.Exception </p>
Run Code Online (Sandbox Code Playgroud)
我做了类似于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);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码使用了我的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));
}
}
Run Code Online (Sandbox Code Playgroud)
注意,上面使用NLog记录错误详细信息,但可以轻松更改以支持其他内容.此外,此方法在解析ErrorController时会尊重您的IoC容器.
| 归档时间: |
|
| 查看次数: |
15413 次 |
| 最近记录: |