5

I'm making a WCF web service that will return a json object, but I keep getting a 400 bad request error when I try to make an AJAX call:

OPTIONS http://localhost:55658/WebServiceWrapper.svc/GetData?_=1318567254842&value=97            HTTP/1.1
Host: localhost:55658
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
DNT: 1
Connection: keep-alive
Origin: http://localhost:3000
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type

HTTP/1.1 400 Bad Request
Server: ASP.NET Development Server/10.0.0.0
Date: Fri, 14 Oct 2011 04:40:55 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: private
Content-Length: 0
Connection: Close

Here is my AJAX call:

$.ajax({
  contentType: 'application/json',
  url: 'http://localhost:55658/WebServiceWrapper.svc/GetData',
  dataType: 'json',
  data: {
    value: 97
  },
  success: function (data) {
    alert('success' + data);
  },
  error: function(XMLHttpRequest, textStatus, errorThrown) {
    alert('failure' + errorThrown);
  }
});

Here is my WCF service definition:

public class WebServiceWrapper : IWebServiceWrapper
{
    public object GetData(int value)
    {
        return new 
        {
            ReturnValue = string.Format("You entered: {0}", value)
        };
    }
}

And it's interface:

[ServiceContract]
public interface IWebServiceWrapper
{
    [OperationContract]
    object GetData(int value);
}

I know I've solved this problem before, but I can't remember what I had done before. Any help would be greatly appreciated as the hole I'm putting in the wall is just getting bigger and bigger.

jishi
  • 22,747
  • 6
  • 45
  • 73

3 Answers3

1

There a couple of things you may need to do (or check if you have done):

Your GetData OperationContract needs to be decorated with [WebGet] attribute.


    [WebGet]
    [OperationContract]
    object GetData(int value);

Your WebServiceWrapper class needs to be decorated with [AspNetCompatibilityRequirements] attribute (Add a reference to System.ServiceModel.Web for this to be available)


    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class WebServiceWrapper : IWebServiceWrapper

The return value from GetData operation will need to be wrapped. An easy way is to use a JavaScriptSerializer to serialize the object to json


    var serializer = new JavaScriptSerializer();
    return serializer.Serialize(new
                                {
                                    ReturnValue = string.Format("You entered: {0}", value)
                                });

You need to make sure you are using a [webHttpBinding] in your endpoints (client and services)

<endpoint ... binding="webHttpBinding" ... />

I dont know if this next thing is mandatory, but you may need an endpoint behaviour that enables web script

<endpointBehaviors>
    <behavior name="[endpointBehaviorName]">
        <enableWebScript/>
    </behavior>
</endpointBehaviors>

You will obviously need to refer to this behavior configuration in your endpoint(s)

<endpoint ... behaviorConfiguration="[endpointBehaviorName]" ... />
John Gathogo
  • 4,202
  • 1
  • 29
  • 46
0

Looking at your request you are making an OPTIONS request rather than a GET, which I think jQuery does automatically if you try to do a cross-site XHR request, see this question:

Why am I getting an OPTIONS request instead of a GET request?

I'm not even sure that your server supports the OPTIONS method, hence your 400 error.

Even different port numbers are considered cross-site requests, so you'd better make a proxy page on the actual web site that makes the HTTP request to your WCF Service.

Community
  • 1
  • 1
jishi
  • 22,747
  • 6
  • 45
  • 73
0

You seem to be violating the same origin policy restriction. You cannot send cross domain AJAX requests. Your application is hosted on http://localhost:3000 and you are trying to send an AJAX request to http://localhost:55658. That's impossible. You can send AJAX requests only to http://localhost:3000. You could use JSONP to circumvent this restriction. And here's another article on MSDN.

Darin Dimitrov
  • 960,118
  • 257
  • 3,196
  • 2,876