这个标题搞砸了,但我盯着它看了10分钟,我真的不知道如何更好地表达它。
我正在使用 .NET 4.6
在抽象BaseAuthorizedController
抛出异常,用[Authorize]
、BeginExecute
重写的方法进行修饰。
代码行如下所示:
var userId = requestContext.HttpContext.User.Identity.GetUserId();
该请求是关于一个不再存在的静态文件。稍后会详细介绍。
例外情况是:Object reference not set to an instance of an object.
,堆栈跟踪:
[NullReferenceException: Object reference not set to an instance of an object.]
<namespace>.BaseAuthorizedController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) in <path>ControllersBaseAuthorizedController.cs:35
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +16
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +52
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +30
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +128
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +369
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +48
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +103
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +48
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +159
HttpContext.User
对象为空。这是有道理的,因为它是一个简单的静态文件请求。我不明白的是,当根本没有控制器处理请求时,为什么首先调用BeginExecute
方法?我相信没有控制器,它派生自BaseAuthorizedController
,可以处理此请求。
此外,仅当在文件目录下请求不存在的文件时,才会发生这种情况。
用一些例子来澄清:
localhost:1000/non-existing-file.txt
- 返回404
.localhost:1000/files/existing-file.txt
- 以纯文本形式返回文件的内容。localhost:1000/files/not-existing-file
- 返回404
.localhost:1000/files/not-existing-file.txt
- 调用BeginExecute
,User
为空,响应为500
。
我收集了什么:
- 它似乎只发生在文件扩展名存在时 -
.
后跟任何符号 - 它似乎只发生在
/files/
.没有FilesController
,只有Files
目录,包含静态文件。也没有区域或自定义路由映射到/files/*
,这可以解释对BaseAuthorizedController
的调用。
关于什么可能导致这种行为的任何想法?
事实证明,这是IIS和路由问题的混合:
- 路由 - 在我的项目中实际上有一个
FillesController
,但是它在单独的区域中注册,因此它不应该与此路由匹配。但是,确实如此,这导致了空引用异常。 IIS - 我通过在
Web.config
-modules
中添加runAllManagedaModulesForAllRequests="true"
来解决此问题。这是它现在的样子:<modules runAllManagedModulesForAllRequests="true"> <remove name="FormsAuthenticationModule" /> <remove name="UrlRoutingModule-4.0" /> <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule"/> <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler"/> <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" /> <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler"/> <add name="ClearServerError" type="Suls.Web.Common.HttpModules.ClearServerErrorModule" /> </modules>
我不明白为什么会解决问题,因为据我所知,表单 MS 文档此设置只是覆盖preCondition
.
由于某种原因,我无法将这种类似 xml 的语法作为代码发布,所以我使用了内联格式。
如果有人有很好的解释,我很乐意接受他们的回答