2017-02-14 1 views
1

Wenn ich einen put an meine API senden, bekomme ich zuerst die Methode OPTIONS und einen Fehler. Es trifft dann wieder meine ausgewählte Aktionsmethode und es enthält die Put-Info.CORS Ausgabe auf Put

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; 
     } 

Ich habe eine Klasse, die meine Preflight-Anfrage behandelt.

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)); 
      } 

Ich habe auch meinen webconfig hinzugefügt

<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> 

Wenn ich meine Put Ajax-Aufruf senden erhalte ich einen Fehler. Es trifft meine Methode und führt meine Aktion aus, aber es sendet einen Fehler. Wenn ich die Put-Anfrage per Postbote abschicke, habe ich kein Problem. Wenn ich es vom Client sende, erhalte ich einen Fehler, weil die erste Methode {OPTIONS} ist. Was vermisse ich? Hier ist mein Ajax

setzen
$.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() { 

Antwort

1

fand ich die Antwort in ein paar andere Fragen. Die Lösung ist so einfach, dass es weh tut. Wenn dieses Problem auftritt, fügen Sie in Ihrem Controller eine Optionsmethode hinzu.

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