Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to call wcf restful service from fiddler by JSON request?

Tags:

json

c#

wcf

fiddler

I am new in wcf restful service. I couldn’t find the problem which was, why my wcf restful service give ‘bad request’. I use .NET 4.0.

My service is:

[OperationContract(Name="Add")]
[WebInvoke(UriTemplate = "test/", Method = "POST",
          ResponseFormat=WebMessageFormat.Json,
          RequestFormat=WebMessageFormat.Json )]
public int Add(Number n1)
{
    res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2);
    return res;
}

Data are..

[Serializable]
    public class Number
    {
        public int Number1 { get; set; }
        public int Number2 { get; set; }
    }

When I call from fiddler its return ‘HTTP/1.1 400 Bad Request’

My fiddler request header is:

User-Agent: Fiddler
Host: localhost:4217
Content-Type: application/json; charset=utf-8

And request body is:

{"Number1":"7","Number2":"7"}

And response header is:

HTTP/1.1 400 Bad Request
Server: ASP.NET Development Server/10.0.0.0
Date: Sun, 14 Aug 2011 18:10:21 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 5450
Cache-Control: private
Content-Type: text/html
Connection: Close

But if I call this service by C# client program it is ok.

My client code is:

uri = "http://localhost:4217/Service1.svc/";
Number obj = new Number() { Number1 = 7, Number2 = 7 };
using (HttpResponseMessage response = new HttpClient().Post(uri+"test/",
       HttpContentExtensions.CreateDataContract(obj)))
{
    string res = response.Content.ReadAsString();
    return res.ToString();
}

please help me........

Thanks.

like image 867
Ashraf Avatar asked Aug 14 '11 18:08

Ashraf


2 Answers

The way you'll find out the issue with your code is to enable tracing on the server, and it will have an exception explaining the problem. I wrote a simple test with your code, and it had a similar error (400), and the traces had the following error:

The data contract type 'WcfForums.StackOverflow_7058942+Number' cannot be
deserialized because the required data members '<Number1>k__BackingField,
<Number2>k__BackingField' were not found.

Data types marked with [Serializable] serialize all the fields in the object, not properties. By commenting out that attribute, the code actually works out fine (the type then falls into the "POCO" (Plain Old Clr Object) rule, which serializes all public fields and properties.

public class StackOverflow_7058942
{
    //[Serializable]
    public class Number
    {
        public int Number1 { get; set; }
        public int Number2 { get; set; }
    }
    [ServiceContract]
    public class Service
    {
        [OperationContract(Name = "Add")]
        [WebInvoke(UriTemplate = "test/", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        public int Add(Number n1)
        {
            int res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2);
            return res;
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
        host.Open();
        Console.WriteLine("Host opened");

        WebClient c = new WebClient();
        c.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8";
        c.Encoding = Encoding.UTF8;
        Console.WriteLine(c.UploadString(baseAddress + "/test/", "{\"Number1\":\"7\",\"Number2\":\"7\"}"));

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
like image 196
carlosfigueira Avatar answered Sep 24 '22 00:09

carlosfigueira


One thing you are doing wrong is the format of the request object. Chang it to:

{ n1: { "Number1":"7","Number2":"7"} }

The parameter names are the root property names of the json object passed to a wcf json endpoint.

I have a sample wcf service on git. Amongst other things, it has a json endpoint and in the Default.asmx I use jquery to make a call to it. I would suggest you construct a similar webpage (host it on the same website as the WCF service) that calls your json service via jquery and test the service with that while fiddler is running to get a sample request. This will be easier and less error prone than constructing the request yourself since jquery will take care of lots of details in the header.

The sample jquery ajax code for calling my echo service that you can adapt for your service is as follows:

    $("#btnEchoString").click(function () {
        var request = $("#request");
        var response = $("#response");
        $.ajax({
            url: 'EchoService.svc/JSON/Echo',
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify({ request: request.val() }),
            dataType: "json",
            success: function (data) {
                response.val(data.d);
            },
            error: function (request, status, error) {
                //TODO: do something here
            }
        });
    });
like image 37
Justin Dearing Avatar answered Sep 20 '22 00:09

Justin Dearing