Search code examples
jqueryajaxwcfjsonpparse-error

WCF 4, JSONP, and jQuery cause parsererror


I've tried nearly everything I can think of, but I'm still running into issues with my ajax calls to a WCF service.

My WCF service has a method like below:

//[WebInvoke(ResponseFormat = WebMessageFormat.Json, Method = "POST")]
[WebGet]    
public string Test(int value)
{
    return string.Format("You entered: {0}", value);
}

As mentioned on Twitter by Patrick Thomas, I've also tried using [WebGet(BodyStyle = WebMessageBodyStyle.Wrapped)] and [WebGet(BodyStyle = WebMessageBodyStyle.WrappedResponse)] with no luck.

And configuration like so:

<system.serviceModel>
    <behaviors>
        <serviceBehaviors>
            <behavior>
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="RestEndpoint">
                <enableWebScript/>
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <bindings>
        <webHttpBinding>
            <binding name="NoSecurityRestBinding" crossDomainScriptAccessEnabled="true">
                <security mode="None" />
            </binding>
        </webHttpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <services>
        <service name="WebServices.TestService">
            <endpoint address="" binding="webHttpBinding" contract="WebServices.ITestService" bindingConfiguration="NoSecurityRestBinding" behaviorConfiguration="RestEndpoint" />
        </service>
    </services>
</system.serviceModel>

The service is located on a different domain, so I'm formatting my data as JSONP:

$.ajax({
    cache: false,
    async: true,
    type: "GET", // Was "POST"
    dataType: "jsonp",
    url: "http://mydomain.com/TestService.svc/Test?callback=?",
    data: dataToPost,
    contentType: "application/json;charset=utf-8",
    success: function (msg) {
        var testMsg = JSON.parse(msg);
        var status = testMsg.TestResult;
        alert(status);
    },
    error: function (msg) {
        alert('Please email Jason with this exception: ' + msg.statusText);
    }
});

And I'm getting:

"parsererror"

"jQuery16408722478272714725_1332817261195 was not called"

What can I possibly be doing wrong? I did verify that all of the WCF binaries are 4.0.

Thanks in advance for your help!


Solution

  • You don't want the enableWebScript behavior applied to the endpoint. That specifically enables support for Microsoft's ASP.NET AJAX client stack which has a specific JSON encoding for all request/responses. Replace that with just webHttp instead and see if that solves your problem. Everything else looks ok to me.

    The next thing I would suggest is setting the automaticFormatSelection attribute of the webHttp behavior element to true as well. This way it'll make sure to serialized the response as JSON when it detects the accepted content type of the HTTP request is JSON.

    Update

    What I just remembered is that, since this is JSONP, the request is going to come from a <script/> tag and therefore WCF will probably default to an XML response. Therefore you also want to set defaultOutgoingResponseFormat="Json" on the webHttp behavior as well so that it will, by default, format responses using JSON.

    As a side note, it's pointless to set the contentType on the jQuery AJAX request because there is no body for JSONP requests since it's all querystring based.