1

I am trying to set up a simple WCF REST service that we will be able to call from jquery. When I visit the URL in the browser, I get a response back. When I attempt to send an HTTPRequest directly (using the Firefox plugin RESTClient), I get a response back. These responses look correct to me, containing headers and a string of JSON and apparently nothing else.

However, when I call this same service via a jquery.get() or jquery.post() call, nothing happens. Using the jquery.ajax() call reveals the error callback gets called, but to me the data given to the error callback doesn't give me clues as to why this isn't working.

<a id="thelink" href="javascript:void(0)">GO</a>
<script type="text/javascript">
    function doAjax() {
        $.ajax({type: "POST",
                dataType: "json", // see note below
                url: "http://localhost:54459/MySimpleService.svc/json/24",
                success: function(jqXHR, textStatus) {
                             alert("success");
                         },
                error: function(jqXHR, textStatus, errorThrown) {
                             alert("error");
                         }
               });
        }
    $('#thelink').click(doAjax);
</script> 

Note: for the dataType parameter I have tried all of "text", "json", "jsonp" and leaving the parameter off. Similarly, I have tried with both GET and POST (modifying the web service to respond to GET or POST respectively).

The method called at that endpoint doesn't do anything spectacular that should be failing -- it simply concatenates the string to a constant and returns (just testing at this point, it will clearly do more interesting things in the future)

Firefox shows me getting back 200 OK when I click the link.

The WCF service is running out of my Visual Studio 2010 debug environment. It hits breakpoints placed in the method that responds to this service method.

I have tried accessing the html posted above from a file on my local machine (port 80) as well as hosting it elsewhere, with the same results. Could this be a security issue?

The values passed to the error callback don't seem terribly helpful:

  • jqXHR - readyState : 0, status : 0, statusText : error
  • textStatus - "error"
  • errorThrown - ""

So, why does my service seem to work, for GET or POST, when I call the url in a browser or RESTClient, but fail when I attempt to call it from jquery.ajax()?

EDIT: after more tests based on the comments I received, I tried hosting the page with the javascript on the same port as the web service, and this shows success. In my real-world scenarios, I won't have the luxury of hosting the client side code and the web service on the same domain/port. I'm assuming this is a security model issue -- where do I look to allow this sort of access (whitelisting domains/ports or otherwise)

PeterL
  • 1,397
  • 11
  • 15
  • If you pull up the URL above in a browser with no parameters, you get results? Are you visiting the URL from `http://localhost:54459` or a different domain (or different port)/ – Eli Gassert Nov 29 '12 at 21:22
  • You are sending your ajax request to localhost:54459. Is that the same hostname that you used to request the origin page? – slashingweapon Nov 29 '12 at 21:23
  • I get results (if I have it set to GET -- if I have it set to POST I get "Method not allowed" when browsing, but I can still reach it using RESTClient). I am visiting exactly the link posted -- I am on the local machine and can access it on localhost:54459. The page my javascript is on is hosted on port 80 (so http://localhost/ajaxtest.html) – PeterL Nov 29 '12 at 21:29
  • If I drop ajaxtest.html into my service directory I get success -- this would seem to point to it being some sort of security issue. In my real world scenario I won't have the luxury of the client code and service being hosted in the same location. Is there a way I can whitelist certain domains or otherwise allow hosting of the javascript on a different domain/port than the web service? – PeterL Nov 29 '12 at 21:32

2 Answers2

1

The issue seemed to be in my web.config; as we worked out in comments, the issue is one of cross-domain security. I was already using a webHttpBinding on my endpoint, but did not realize it needed to be configured:

<system.serviceModel>
    <bindings>
        <webHttpBinding>
            <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true"/>
        </webHttpBinding>
    </bindings>
    ...
</system.serviceModel>

Setting crossDomainScriptAccessEnabled="true" seems to have done the trick. Note that I already have <serviceMetadata httpGetEnabled="true"/> as part of my service behavior.

PeterL
  • 1,397
  • 11
  • 15
0

make sure you have already configured your service to be called from script clients: adding a couple of elements in web.config in your service:

<behaviors>
 <endpointBehaviors>
  <behavior name="webScriptEnablingBehavior">
  <enableWebScript/>
 </behavior>
</endpointBehaviors>

more info here: http://msdn.microsoft.com/en-us/library/bb763177(v=vs.90).aspx

hope it helps,

Jorge Alvarado
  • 2,664
  • 22
  • 33
  • If I add `` I get the following exception when I try and access the service: `System.InvalidOperationException: Endpoints using 'UriTemplate' cannot be used with 'System.ServiceModel.Description.WebScriptEnablingBehavior'.` -- I use the `UriTemplate` attributes on my service methods to map them to URLs – PeterL Nov 29 '12 at 21:37
  • ok I see, seams like they already discussed that here in SO, look: http://stackoverflow.com/questions/2471358/combined-soap-json-xml-in-wcf-using-uritemplate you have to make a workaround but seems it works – Jorge Alvarado Nov 29 '12 at 21:44