Asp.net 为什么一个含糊不清的控制器尝试错误处理的例外会扰乱管道?
我正在尝试一些错误处理,而这个特定的错误似乎把事情搞砸了 我有一个订阅HttpApplication.Error事件处理程序的HttpModule(见下文),在这里我清除错误并编写一些虚拟响应内容 这对“正常”应用程序错误很好,但是当我得到关于不明确控制器的错误时,它会像往常一样进入处理程序,但是更改的响应被完全忽略,管道中的执行流似乎有一些小故障,对MVC之外的相同资源创建IIS子请求,根据请求的原始路径,导致IIS错误页面,该页面无法列出目录或文件不存在 复制:Asp.net 为什么一个含糊不清的控制器尝试错误处理的例外会扰乱管道?,asp.net,asp.net-mvc,iis,asp.net-mvc-5,iis-8,Asp.net,Asp.net Mvc,Iis,Asp.net Mvc 5,Iis 8,我正在尝试一些错误处理,而这个特定的错误似乎把事情搞砸了 我有一个订阅HttpApplication.Error事件处理程序的HttpModule(见下文),在这里我清除错误并编写一些虚拟响应内容 这对“正常”应用程序错误很好,但是当我得到关于不明确控制器的错误时,它会像往常一样进入处理程序,但是更改的响应被完全忽略,管道中的执行流似乎有一些小故障,对MVC之外的相同资源创建IIS子请求,根据请求的原始路径,导致IIS错误页面,该页面无法列出目录或文件不存在 复制: 创建一个新的模板化MVC项目
public class HttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.Error += HandleApplicationError;
}
private void HandleApplicationError(object sender, EventArgs e)
{
var response = HttpContext.Current.Response;
var server = ((HttpApplication)sender).Server;
server.ClearError();
response.Clear();
response.Write("Hello world");
}
public void Dispose()
{
}
}
这里发生了什么?当我试图清除错误并更改响应时,当我们得到关于不明确控制器的异常时,为什么会出现问题?该行为取决于引发请求处理管道异常的位置
- 在控制器不明确的情况下,路由系统会找到与url匹配的路由,并尝试获取将处理请求的IHttpHandler。但是,在尝试获取IHttpHandler时引发异常,请检查此堆栈跟踪:
at System.Web.Mvc.DefaultControllerFactory.GetControllerTypeWithinNamespaces(RouteBase route, String controllerName, HashSet`1 namespaces) at System.Web.Mvc.DefaultControllerFactory.GetControllerType(RequestContext requestContext, String controllerName) at System.Web.Mvc.DefaultControllerFactory.System.Web.Mvc.IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName) at System.Web.Mvc.MvcRouteHandler.GetSessionStateBehavior(RequestContext requestContext) at System.Web.Mvc.MvcRouteHandler.GetHttpHandler(RequestContext requestContext) at System.Web.Mvc.MvcRouteHandler.System.Web.Routing.IRouteHandler.GetHttpHandler(RequestContext requestContext) at System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) at System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object s atder, Ev attArgs e) at System.Web.HttpApplication.SyncEv attExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
由于路由模块无法获取处理程序,IIS将尝试使用其他模块处理它。这意味着它将尝试使用IIS上默认启用的at WebApplication3.Controllers.HomeController.ThrowError() at g:\Documents\Visual Studio 2012\Projects\WebApplication3\WebApplication3\Controllers\HomeController.cs:line 32 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__36(IAsyncResult asyncResult, ActionInvocation innerInvokeState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3c() at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass45.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3e() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass30.<BeginInvokeActionMethodWithFilters>b__2f(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass1e.<>c__DisplayClass28.<BeginInvokeAction>b__19() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass1e.<BeginInvokeAction>b__1b(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) at System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(IAsyncResult asyncResult, ProcessRequestState innerState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
和DirectoryListingModule
为请求提供服务StaticFileModule
- 当在控制器操作中引发异常时,请求已经分配了一个IHttpHandler,该IHttpHandler正在处理该请求。检查不同的堆栈跟踪:
at System.Web.Mvc.DefaultControllerFactory.GetControllerTypeWithinNamespaces(RouteBase route, String controllerName, HashSet`1 namespaces) at System.Web.Mvc.DefaultControllerFactory.GetControllerType(RequestContext requestContext, String controllerName) at System.Web.Mvc.DefaultControllerFactory.System.Web.Mvc.IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName) at System.Web.Mvc.MvcRouteHandler.GetSessionStateBehavior(RequestContext requestContext) at System.Web.Mvc.MvcRouteHandler.GetHttpHandler(RequestContext requestContext) at System.Web.Mvc.MvcRouteHandler.System.Web.Routing.IRouteHandler.GetHttpHandler(RequestContext requestContext) at System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) at System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object s atder, Ev attArgs e) at System.Web.HttpApplication.SyncEv attExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
at WebApplication3.Controllers.HomeController.ThrowError() at g:\Documents\Visual Studio 2012\Projects\WebApplication3\WebApplication3\Controllers\HomeController.cs:line 32 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__36(IAsyncResult asyncResult, ActionInvocation innerInvokeState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3c() at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass45.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3e() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass30.<BeginInvokeActionMethodWithFilters>b__2f(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass1e.<>c__DisplayClass28.<BeginInvokeAction>b__19() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass1e.<BeginInvokeAction>b__1b(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) at System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(IAsyncResult asyncResult, ProcessRequestState innerState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) at System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
谢谢,看起来不错,但有一件事我仍然不明白,那就是如果我们禁用自定义错误处理,“UrlRoutingModule-4.0”会导致默认错误页面,并且它不会尝试DirectoryListingModule或StaticFileModule。如果您描述的行为是由IIS查找处理程序的失败尝试引起的,为什么只有在我尝试清除响应时才会触发此操作?我清除响应是否会导致IIS对刚才发生的事情产生误解?可能是因为当我不清除错误时,IIS会在尝试获取处理程序失败后将错误注册到管道中,并使用此操作在另一个处理程序中生成错误页,独立于获取处理程序的原始失败尝试。因此,当我清除错误时,IIS不会触发错误页面模块并继续搜索…而不调用
错误将不断扩展,直到asp最终处理它,生成死亡的黄屏。因此,如果您删除错误处理代码,或注释调用服务器。ClearError
的行,您将看到YSODDo,您是否确切地知道此错误是如何升级的?是否都在UrlRoutingModule中处理?我在看跟踪文件,但没什么收获。希望有一种更明确的方式来遵循IIS的流程。我恐怕不知道导致YSOD的asp net内部异常处理过程,但我猜它将是默认asp net请求管道的一部分。如果将ClearError
和Application\u Error
方法添加到global.asax,您将看到在错误发生后触发结束请求,并且清除响应并用YSOD替换,因此可能有一个全局模块订阅了OnError事件。(我不熟悉此代码,因此可能是错的)Application\u EndRequest