好吧,我一直在为此this头……
设置:
问题:
我在每个经过身份验证的请求上都收到以下错误消息:
System.Web.HttpException (0x80004005): Server cannot set status after HTTP headers have been sent.
at System.Web.HttpResponse.set_StatusCode(Int32 value)
at System.Web.HttpResponseWrapper.set_StatusCode(Int32 value)
at System.Web.Http.WebHost.HttpControllerHandler.<CopyResponseStatusAndHeadersAsync>d__31.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.WebHost.HttpControllerHandler.<CopyResponseAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at System.Web.Http.WebHost.HttpControllerHandler.<ProcessRequestAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at System.Web.TaskAsyncHelper.EndTask(IAsyncResult ar)
at System.Web.HttpTaskAsyncHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)
到目前为止完成的调查:
上面列出的错误仅在OPTIONS动词上发生。
该错误表明,在要求其设置状态码之前已经发送了 header 。
仅出现1条错误记录-在Elmah中,“SendAsync”方法被击中两次-一次用于OPTIONS预检,一次用于GET或POST。这告诉我,这仅在一个请求(OPTIONS请求)上发生。
为了通过飞行前检查,我使用了以下命令:(global.asax)
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
}
这会将响应传递到我的处理程序中,但同时还将OPTIONS动词传递到此代码中,我认为它应该:
//Capture incoming request by overriding SendAsync method
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
//validate credentials, set CurrentPrincipal and Current.User if valid
if (ValidateCredentials(request.Headers.Authorization))
{
Thread.CurrentPrincipal = new MyPrincipal(_userName);
HttpContext.Current.User = new MyPrincipal(_userName);
}
// Execute base.SendAsync to execute default actions
// and once it is completed, capture the response object and add
// WWW-Authenticate header if the request was marked as (401) unauthorized.
return base.SendAsync(request, cancellationToken).ContinueWith(task =>
{
HttpResponseMessage response = task.Result;
if (response.StatusCode == HttpStatusCode.Unauthorized && !response.Headers.Contains("WWW-Authenticate"))
{
response.Headers.Add("WWW-Authenticate", "Basic");
}
return response;
});
}
现在在调试器中,我看到OPTIONS可以通过并触发405-不允许的方法,但是当它通过elmah时会出现500错误-服务器在发送HTTP header 后无法设置状态。
我没有在我的任何 Controller 上放置OPTIONS,所以这也许可以解释405-但请求不应走得那么远。
所以-这听起来像是配置的东西?使困惑。
我的cors配置是:
<!-- BEGIN: Enable CORS -->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="accept, authorization, origin, content-type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<remove name="WebDAV"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<!-- END: Enable CORS -->
到目前为止,我的想法
该错误不是“FatalError”,并且程序仍会触发,因为预检请求不会影响我所知道的任何事情,因此可以忽略该错误吗?好吧,不!这是一个错误!
现在-经过我的研究,看来这是IIS泄漏到我的应用程序中,我也许可以通过config停止它-但是如何?
如果不是那样,那么到底是什么原因造成的呢?它来自哪里?我该如何解决?不知道...
所以我依靠Stack Overflow上那些 Nerd 的英明智慧...
帮助!!!!!!!
最佳答案
在Response.End();
之后放置一个Response.Flush();
因此,对于预检请求,您应该有一个空响应。
至少这为我解决了这个问题。
关于asp.net - 发送HTTP header 后服务器无法设置状态-Web API CORS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29709477/