2017-02-14 72 views
1

當我發送put給我的Api時,我首先得到方法OPTIONS並出錯。然後它再次點擊我的選擇操作方法,它包含放置信息。關於Put的CORS問題

public HttpActionDescriptor SelectAction(HttpControllerContext controllerContext) 
     { 
      var request = controllerContext.Request; 
      if (request.IsInspectRequest()) 
      { 
       var simulate = new ActionSelectSimulator(); 
       request.Properties[RequestHelper.ActionCache] = simulate.Simulate(controllerContext); 
      } 

      var selectedAction = _innerSelector.SelectAction(controllerContext); 

      return selectedAction; 
     } 

我有一個類來處理我的預檢請求。

public class XHttpMethodOverrideHandler : DelegatingHandler 
    { 
     static readonly string[] httpOverrideMethods = { "PUT", "DELETE" }; 
     static readonly string[] accessControlAllowMethods = { "POST", "PUT", "DELETE" }; 
     static readonly string httpMethodOverrideHeader = "X-HTTP-Method-Override"; 
     static readonly string ORIGIN_HEADER = "ORIGIN"; 
     static readonly string accessControlAllowOriginHeader = "Access-Control-Allow-Origin"; 
     static readonly string accessControlAllowMethodsHeader = "Access-Control-Allow-Methods"; 
     static readonly string accessControlAllowHeadersHeader = "Access-Control-Allow-Headers"; 

     protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
     { 
      try 
      { 
       if (request.Method == HttpMethod.Post && request.Headers.Contains(httpMethodOverrideHeader)) 
       { 
        var httpMethod = request.Headers.GetValues(httpMethodOverrideHeader).FirstOrDefault(); 
        if (httpOverrideMethods.Contains(httpMethod, StringComparer.InvariantCultureIgnoreCase)) 
         request.Method = new HttpMethod(httpMethod); 
       } 

       var httpResponseMessage = base.SendAsync(request, cancellationToken); 

       if (request.Method == HttpMethod.Options && request.Headers.Contains(ORIGIN_HEADER)) 
       { 
        httpResponseMessage.Result.Headers.Add(accessControlAllowOriginHeader, request.Headers.GetValues(ORIGIN_HEADER).FirstOrDefault()); 
        httpResponseMessage.Result.Headers.Add(accessControlAllowMethodsHeader, String.Join(", ", accessControlAllowMethods)); 
        httpResponseMessage.Result.Headers.Add(accessControlAllowHeadersHeader, httpMethodOverrideHeader); 
        httpResponseMessage.Result.StatusCode = HttpStatusCode.OK; 
       } 
       else if (request.Headers.Contains(ORIGIN_HEADER)) 
        httpResponseMessage.Result.Headers.Add(accessControlAllowOriginHeader, request.Headers.GetValues(ORIGIN_HEADER).FirstOrDefault()); 

       return httpResponseMessage; 
      } 
      catch (Exception ex) 
      { 
       ILoggerService logger = IocContainer.Container.TryGetInstance<ILoggerService>(); 
       if (logger != null) 
       { 
        logger.Error(ex); 
       } 
       return Task.FromResult<HttpResponseMessage>(request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex)); 
      } 

我也紛紛加入到我的webconfig

<handlers> 
     <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
     <remove name="OPTIONSVerbHandler" /> 
     <remove name="TRACEVerbHandler" /> 
     <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    </handlers> 

當我把我認沽Ajax調用我收到一個錯誤。它擊中我的方法並執行我的操作,但它發送錯誤。如果我通過郵遞員發送放入請求,那麼我沒有問題。如果我從客戶端發送它,我會得到一個錯誤,因爲它得到的第一個方法是{OPTIONS}。我錯過了什麼? 這裏是我的Ajax把

$.ajax({ 
        url: "http://localhost:61148/api/mycontroller", 
        contentType: "application/x-www-form-urlencoded; charset=UTF-8", 
        async: true, 
        type: "PUT", 
        data: sendData, 
        datatype: 'json', 
        crossDomain: true, 
        success: function() { 

回答

1

我找到了答案一對夫婦的其他問題。解決方案非常簡單,很痛苦。如果您遇到此問題,請在控制器中添加一個選項方法。

public HttpResponseMessage Options() 
{ 
    var response = new HttpResponseMessage 
    { 
     StatusCode = HttpStatusCode.OK 
    }; 
    return response; 
}