好吧,我一直在抨击这个人的血腥......
设置:
问题:
我在每个经过身份验证的请求中收到以下错误:
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动词。
错误表示标题已在被要求设置其状态代码之前已发送。
只出现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头后设置状态。 / p>
我没有把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,我可以通过配置停止 - 但是如何?
如果那不是它那么到底是什么造成的呢?它来自哪里?我该如何解决?不知道......
所以我依靠Stack Overflow上同伴们的勇敢智慧......
HELP !!!!!!!
答案 0 :(得分:21)
在Response.End();
Response.Flush();
因此,您应该对预检请求进行空响应。
至少这为我解决了这个问题。