asp.net - 发送HTTP header 后服务器无法设置状态-Web API CORS

标签 asp.net asp.net-web-api cors

好吧,我一直在为此this头……

设置:

  • 我有一个设置了基本身份验证的Web Api 2.0项目。
  • 我在web.config中启用了CORS
  • 我有ELMAH记录错误
  • 我有一个DelegatingHandler处理传入的请求-(下面的代码)
  • 我有一个非常特定的数据结构,因此我没有使用Microsoft的Membership或Identity。
  • 我正在刷新所有使用OPTIONS动词
  • 的请求

    问题:

    我在每个经过身份验证的请求上都收到以下错误消息:
    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/

    相关文章:

    asp.net - 更改 ASP.NET 缓存项过期的频率?

    c# - 一个按钮的 OnClientClick 和 Click 事件没有触发 - FireFox 中的问题

    c# - 使用javascript选中和取消选中转发器控件中的复选框?

    asp.net-web-api - 无法在 ASP.NET Core 1.0 中启用跨源请求 (CORS)

    c# - 为什么我的 [ActionName] 属性不起作用?

    javascript - Chrome 扩展被 rails API 阻止

    c# - 自定义 AuthorizeAttribute OnAuthorizationAsync 函数

    javascript - 从不同域中的父窗口获取 iframe 中的 javascript 变量

    cors - 同源策略和 CORS - 有什么意义?

    javascript - 在javascript中将项目插入数组