title: jQuery .ajax() 405 (Method Not Allowed) / Cross Domain
body: <p>I have seen so many questions on SO about this, but I can't find what is missing in my code.</p>
  
  <p>I'm implementing <a href="http://enable-cors.org/index.html" rel="nofollow noreferrer">CORS</a> cause I don't want to use <code>JSONP</code>.</p>
  
  <p>I know this is a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests" rel="nofollow noreferrer">preflighted request</a> and I think I'm adding the correct <code>headers</code>.</p>
  
  <p>The error is that the website doesn't seem to like my <code>WCF</code> and every time I do a request, an <code>OPTION</code> method called is made even tho I have the <code>Access-Control-Allow-Methods</code> header.</p>
  
  <p>I just want to make a <code>POST</code> call to my <code>WCF</code> with a <code>contentType: "application/json",</code></p>
  
  <p>The <code>WCF</code> is self hosted, the web application is on <code>IIS 7.5</code>.</p>
  
  <hr>
  
  <p><strong>What Chrome shows:</strong></p>
  
  <p><img src="https://i.stack.imgur.com/NBPRI.png" alt="enter image description here"></p>
  
  <hr>
  
  <p><strong>What fiddler shows</strong>
  <img src="https://i.stack.imgur.com/084Cr.png" alt="enter image description here"></p>
  
  <hr>
  
  <p><strong>Contract</strong></p>
  
  <pre><code>&lt;OperationContract()&gt;
  &lt;WebInvoke(Method:="POST",
             RequestFormat:=WebMessageFormat.Json,
             ResponseFormat:=WebMessageFormat.Json,
             BodyStyle:=WebMessageBodyStyle.WrappedRequest)&gt;
  &lt;FaultContract(GetType(ServiceFault))&gt;
  Function LookUpPerson(person As Person) _
                       As List(Of Person)
  </code></pre>
  
  <hr>
  
  <p><strong>app.config</strong></p>
  
  <pre><code>&lt;serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" /&gt;
  &lt;bindings&gt;
    &lt;webHttpBinding&gt;
      &lt;binding name="webHttpBindingWithJsonP"
               crossDomainScriptAccessEnabled="true"&gt;
        &lt;security mode="None" /&gt;
      &lt;/binding&gt;
    &lt;/webHttpBinding&gt;
  &lt;/bindings&gt;
  
  &lt;services&gt;
    &lt;service name="Project.Services.Person"&gt;  
      &lt;endpoint address="ws"  binding="wsHttpBinding"     contract="Project.Services.Interfaces.IPublic" /&gt;   
      &lt;endpoint address=""    binding="webHttpBinding"    contract="Project.Services.Interfaces.IPublic"
                behaviorConfiguration="jsonBehavior"/&gt;
      &lt;host&gt;
        &lt;baseAddresses&gt;
          &lt;add baseAddress="http://localhost:8732/" /&gt;
        &lt;/baseAddresses&gt;
      &lt;/host&gt;
    &lt;/service&gt;
  &lt;/services&gt;
  
  &lt;extensions&gt;
    &lt;behaviorExtensions&gt;
      &lt;add name="customHeaders"
           type="Project.Services.Utilities.EnableCrossOriginResourceSharingBehavior, Project.Services, Version=1.0.0.0, Culture=neutral"/&gt;
    &lt;/behaviorExtensions&gt;
  &lt;/extensions&gt;
  
  &lt;endpointBehaviors&gt;
    &lt;behavior name="jsonBehavior"&gt;
      &lt;webHttp/&gt;
      &lt;customHeaders /&gt;
    &lt;/behavior&gt;
  &lt;/endpointBehaviors&gt;
  </code></pre>
  
  <hr>
  
  <p><strong>javascript</strong></p>
  
  <pre><code>$.ajax({
      url: "http://192.168.0.61:8282/Project.Services.Person/LookUpPerson",
      type: "POST",
      contentType: "application/json",
      crossDomain: true,
      dataType: "json",
      data: { person: JSON.stringify(person) },
      success: function (data) {
          // doing something
      },
      error: function (error) {
          // doing something
      }
  });
  </code></pre>
  
  <hr>
  
  <p>On the WCF I have the following handlers, according to <a href="http://enable-cors.org/server_wcf.html" rel="nofollow noreferrer">http://enable-cors.org/server_wcf.html</a></p>
  
  <pre><code>Public Class CustomHeaderMessageInspector
          Implements IDispatchMessageInspector
  
          Private requiredHeaders As Dictionary(Of String, String)
          Public Sub New(headers As Dictionary(Of String, String))
              requiredHeaders = If(headers, New Dictionary(Of String, String)())
          End Sub
  
          Public Function AfterReceiveRequest(ByRef request As System.ServiceModel.Channels.Message,
                                              channel As System.ServiceModel.IClientChannel,
                                              instanceContext As System.ServiceModel.InstanceContext) _
                                          As Object _
                                          Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.AfterReceiveRequest
              Return Nothing
          End Function
  
          Public Sub BeforeSendReply(ByRef reply As System.ServiceModel.Channels.Message,
                                     correlationState As Object) _
                                 Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.BeforeSendReply
              Dim httpHeader = TryCast(reply.Properties("httpResponse"), HttpResponseMessageProperty)
              For Each item In requiredHeaders
                  httpHeader.Headers.Add(item.Key, item.Value)
              Next
          End Sub
  
      End Class
  </code></pre>
  
  <hr>
  
  <p><strong>And</strong></p>
  
  <pre><code>Public Class EnableCrossOriginResourceSharingBehavior
          Inherits BehaviorExtensionElement
          Implements IEndpointBehavior
  
          Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) _
                                          Implements System.ServiceModel.Description.IEndpointBehavior.AddBindingParameters
  
          End Sub
  
          Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As System.ServiceModel.Dispatcher.ClientRuntime) _
                                           Implements System.ServiceModel.Description.IEndpointBehavior.ApplyClientBehavior
  
          End Sub
  
          Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As System.ServiceModel.Dispatcher.EndpointDispatcher) _
                                          Implements System.ServiceModel.Description.IEndpointBehavior.ApplyDispatchBehavior
              Dim requiredHeaders = New Dictionary(Of String, String)()
  
              requiredHeaders.Add("Access-Control-Allow-Origin", "*")
              requiredHeaders.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
              requiredHeaders.Add("Access-Control-Allow-Headers", "Origin, Content-Type, Accept")
              requiredHeaders.Add("Access-Control-Max-Age", "1728000")
  
              endpointDispatcher.DispatchRuntime.MessageInspectors.Add(New CustomHeaderMessageInspector(requiredHeaders))
          End Sub
  
          Public Sub Validate(endpoint As ServiceEndpoint) _
              Implements System.ServiceModel.Description.IEndpointBehavior.Validate
  
          End Sub
  
          Public Overrides ReadOnly Property BehaviorType() As Type
              Get
                  Return GetType(EnableCrossOriginResourceSharingBehavior)
              End Get
          End Property
  
          Protected Overrides Function CreateBehavior() As Object
              Return New EnableCrossOriginResourceSharingBehavior()
          End Function
  
      End Class
  </code></pre>
  
  <p>Sorry for the long post, I wanted to be specific.</p>
  
  <p>Thanks in advance.</p>
  
  <hr>
  
  <p><strong>UPDATE</strong></p>
  
  <p>If I use <code>contentType: "text/plain"</code> I get the error on the chrome console:</p>
  
  <blockquote>
    <p>POST <code>http://192.168.0.61:8282/Project.Services.Person/LookUpPerson</code> 400 (Bad Request)</p>
  </blockquote>