I have seen so many questions on SO about this, but I can't find what is missing in my code.
I'm implementing CORS cause I don't want to use JSONP.
I know this is a preflighted request and I think I'm adding the correct headers.
The error is that the website doesn't seem to like my WCF and every time I do a request, an OPTION method called is made even tho I have the Access-Control-Allow-Methods header.
I just want to make a POST call to my WCF with a contentType: "application/json",
The WCF is self hosted, the web application is on IIS 7.5.
What Chrome shows:

What fiddler shows

Contract
<OperationContract()>
<WebInvoke(Method:="POST",
           RequestFormat:=WebMessageFormat.Json,
           ResponseFormat:=WebMessageFormat.Json,
           BodyStyle:=WebMessageBodyStyle.WrappedRequest)>
<FaultContract(GetType(ServiceFault))>
Function LookUpPerson(person As Person) _
                     As List(Of Person)
app.config
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<bindings>
  <webHttpBinding>
    <binding name="webHttpBindingWithJsonP"
             crossDomainScriptAccessEnabled="true">
      <security mode="None" />
    </binding>
  </webHttpBinding>
</bindings>
<services>
  <service name="Project.Services.Person">  
    <endpoint address="ws"  binding="wsHttpBinding"     contract="Project.Services.Interfaces.IPublic" />   
    <endpoint address=""    binding="webHttpBinding"    contract="Project.Services.Interfaces.IPublic"
              behaviorConfiguration="jsonBehavior"/>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8732/" />
      </baseAddresses>
    </host>
  </service>
</services>
<extensions>
  <behaviorExtensions>
    <add name="customHeaders"
         type="Project.Services.Utilities.EnableCrossOriginResourceSharingBehavior, Project.Services, Version=1.0.0.0, Culture=neutral"/>
  </behaviorExtensions>
</extensions>
<endpointBehaviors>
  <behavior name="jsonBehavior">
    <webHttp/>
    <customHeaders />
  </behavior>
</endpointBehaviors>
javascript
$.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
    }
});
On the WCF I have the following handlers, according to http://enable-cors.org/server_wcf.html
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
And
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
Sorry for the long post, I wanted to be specific.
Thanks in advance.
UPDATE
If I use contentType: "text/plain" I get the error on the chrome console:
POST
http://192.168.0.61:8282/Project.Services.Person/LookUpPerson400 (Bad Request)
I had the same issue and this fixed it for me.
Change
[WebInvoke(Method = "Post")]
to
[WebInvoke(Method = "*")]
because although you accept POST, modern browsers will always send OPTIONS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With