How to pass and consume a JSON parameter to/with RESTful WCF service?
Asked Answered
T

2

8

I am a beginner at RESTful services.

I need to create an interface where the client needs to pass up to 9 parameters.

I would prefer to pass the parameters as a JSON object.

For instance if my JSON is:

'{
    "age":100,
    "name":"foo",
    "messages":["msg 1","msg 2","msg 3"],
    "favoriteColor" : "blue",
    "petName" : "Godzilla",
    "IQ" : "QuiteLow"
}'

And if I need to execute a server side method below in the end:

public Person FindPerson(Peron lookUpPerson)
{
Person found = null;
// Implementation that finds the Person and sets 'found'
return found;
}

Question(s):
How should I make the call from the client-side with the above JSON string? And how can I create a signature and implementation of the RESTful service method that

  • accepts this JSON,
  • parses and deserializes it into Person object and
  • calls / returns the FindPerson method's return value back to client?
Trivium answered 17/12, 2012 at 14:11 Comment(2)
See #13166033Pleasurable
Which language are you using to call the service? JavaScript, C#, something else?Elnoraelnore
E
14

If you want to create a WCF operation to receive that JSON input, you'll need to define a data contract which maps to that input. There are a few tools which do that automatically, including one which I wrote a while back at http://jsontodatacontract.azurewebsites.net/ (more details on how this tool was written at this blog post). The tool generated this class, which you can use:

// Type created for JSON at <<root>>
[System.Runtime.Serialization.DataContractAttribute()]
public partial class Person
{

    [System.Runtime.Serialization.DataMemberAttribute()]
    public int age;

    [System.Runtime.Serialization.DataMemberAttribute()]
    public string name;

    [System.Runtime.Serialization.DataMemberAttribute()]
    public string[] messages;

    [System.Runtime.Serialization.DataMemberAttribute()]
    public string favoriteColor;

    [System.Runtime.Serialization.DataMemberAttribute()]
    public string petName;

    [System.Runtime.Serialization.DataMemberAttribute()]
    public string IQ;
}

Next, you need to define an operation contract to receive that. Since the JSON needs to go in the body of the request, the most natural HTTP method to use is POST, so you can define the operation as below: the method being "POST" and the style being "Bare" (which means that your JSON maps directly to the parameter). Notice that you can even omit the Method and BodyStyle properties, since "POST" and WebMessageBodyStyle.Bare are their default values, respectively).

[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
public Person FindPerson(Peron lookUpPerson)
{
    Person found = null;
    // Implementation that finds the Person and sets 'found'
    return found;
}

Now, at the method you have the input mapped to lookupPerson. How you will implement the logic of your method is up to you.

Update after comment

One example of calling the service using JavaScript (via jQuery) can be found below.

var input = '{
    "age":100,
    "name":"foo",
    "messages":["msg 1","msg 2","msg 3"],
    "favoriteColor" : "blue",
    "petName" : "Godzilla",
    "IQ" : "QuiteLow"
}';
var endpointAddress = "http://your.server.com/app/service.svc";
var url = endpointAddress + "/FindPerson";
$.ajax({
    type: 'POST',
    url: url,
    contentType: 'application/json',
    data: input,
    success: function(result) {
        alert(JSON.stringify(result));
    }
});
Elnoraelnore answered 17/12, 2012 at 21:31 Comment(4)
Very useful answer carlosfigueira! (Can you also add the Javascript call so that it can cover all parts roughly) Thanks!Trivium
I have asked how to replace this jquery ajax call with a JavaScript builtin functions usage only :) (See my last question, if interested :) )Trivium
The sample at msdn.microsoft.com/en-us/library/vstudio/… shows one way of doing that, using the XMLHttpRequest object.Elnoraelnore
WebMessageBodyStyle.WrappedRequest may work for you if Bare causes an error.Counterpoison
R
1

1-Add the WebGet attribute

<OperationContract()> _
        <WebGet(UriTemplate:="YourFunc?inpt={inpt}", BodyStyle:=WebMessageBodyStyle.Wrapped,
                RequestFormat:=WebMessageFormat.Json, ResponseFormat:=WebMessageFormat.Xml)> _
        Public Function YourFunch(inpt As String) As String

2-Use NewtonSoft to serialize/deserialize your json into your object (note the above just takes in String), NewtonSoft is much faster than the MS serializer.

use NewtonSoft for serialization http://json.codeplex.com/

3- your .svc file will contain Factory="System.ServiceModel.Activation.WebServiceHostFactory

4- your web.config will contain

     <behaviors>
      <endpointBehaviors>
        <behavior name="webHttpBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>

...and...

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
Runnymede answered 17/12, 2012 at 14:19 Comment(1)
If you want to pass a JSON input to a WCF service, you shouldn't use [WebGet] - the input should be passed in the request body, so GET shouldn't be used for that. It should use [WebInvoke] instead.Elnoraelnore

© 2022 - 2024 — McMap. All rights reserved.