0

When this "quick one hour" project came up I never thought that 2 days later I would be on Stackoverflow asking this question. However, here we go...

I have a number of external client applications (java, perl, php, c#) that are currently calling GET methods on a WCF REST service that returns JSON. This is working fine and is implemented exactly as you would expect.

I now have a requirement for these same applications to POST JSON into an new method on the original service interface. The C# app uses WebClient, Perl and PHP are using CURL, Java is using some magic that I am not involved with. All of them generate the JSON as a string and then call basic HTTP functionality to POST the data to an endpoint.

The issue is that the JSON we are using does not have a C# class associated with it (for reasons that can't be changed), as such we intend to use strings and json.net to parse/handle the incoming data. As an example, the endpoint could be:

https://magic.myserver.com/service/dataaggregator/

the external applications post a JSON string to this and in the underlying code we parse and handle as necessary.

So the question is a very simple one, how would this be implemented from a service interface perspective? I can handle serialisation/management of the JSON string within the service code without any problems the question is how do I get that string of JSON into the service code in the first place.

At the moment I am thinking that these can't be done using a "normal" WCF REST interface, rather I will have to implement a lower level HTTP listener where I can access the incoming post data directly.

MrEyes
  • 13,059
  • 10
  • 48
  • 68

4 Answers4

1

If you want to accept arbitrary JSON, look here:

http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/071f73bb-e141-4a68-ae61-05635382934f

If that's not what you want, then you may need to clarify your goals in the question.

See also, https://stackoverflow.com/a/7360619 and https://stackoverflow.com/a/2330219

The service interface is like this:

[OperationContract]
public Whatever  MyMethod(DataPacket rawJSON)
{ 
     ....
}

[DataContract]
public class DataPacket
{
  [DataMember]
  public JsonDictionary Registration { get; set; }
}

...where JsonDictionary is defined according to this answer.

You can also code the method to accept a stream, like this:

[OperationContract]
public Whatever  MyMethod(Stream rawJSON)
{ 
     ....
}

...and parse the JSON yourself, according to this answer.

Community
  • 1
  • 1
Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • Added some clarifications to the question : ....how would this be implemented from a service interface perspective? I can handle serialisation/management of the JSON string within the service code without any problems the question is how do I get that string of JSON into the service code in the first place. – MrEyes Jun 19 '12 at 20:59
  • I''m still not clear. I made some updates on my suggestions though. – Cheeso Jun 19 '12 at 21:04
  • Added further clarifications I think I confused things as it isn't arbitary JSON, only one structure will come in but there is, and never will be, a C# class associated with it. So we intend to use json.net to handle the serialisation – MrEyes Jun 19 '12 at 21:07
0

With ASP.NET WebAPI use Anonymous and Weakly-Typed JSON Objects

Look here in section "Anonymous and Weakly-Typed JSON Objects": http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization

Actually it uses JSON.NET so you are able to do it with older .NET REST Technologies. But I am sure that when dealing with mature JSON parsers (not only on .NET), it's possible to parse arbitrary JSON structure like it does Json.NET

UPD: Take a look at this link

http://www.hanselman.com/blog/NuGetPackageOfTheWeek4DeserializingJSONWithJsonNET.aspx

You can even deal with JObject class from Json.NET as dynamic. Parsing Json string can produce JObject

Regfor
  • 8,515
  • 1
  • 38
  • 51
  • Added some clarifications to the question : ....how would this be implemented from a service interface perspective? I can handle serialisation/management of the JSON string within the service code without any problems the question is how do I get that string of JSON into the service code in the first place. – MrEyes Jun 19 '12 at 20:58
  • So, you need to manually parse your Json object on server. For example method mapped to URL where Json is POSTed, could take string as argument and then using Json.NET you can parse any Json structure. But when you have some predefined Json objects "schemas", then it's even easier to parse. – Regfor Jun 19 '12 at 21:06
  • And it's not a problem that there is no class associated with json objects. Manually parsing, anonymous types, or even directly extracting only needed information from incoming Json string – Regfor Jun 19 '12 at 21:09
0

If you want to go with HttpListener here is a sample code (using Json.Net)

HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:8080/");
listener.Start();
Task.Factory.StartNew(() =>
{
    while (true)
    {
        HttpListenerContext context = listener.GetContext();
        ThreadPool.QueueUserWorkItem((o) =>
        {
            HttpListenerContext ctx = (HttpListenerContext)o;
            StreamReader rdr = new StreamReader(ctx.Request.InputStream);
            var postData = rdr.ReadToEnd();
            var dynJson = (JObject)JsonConvert.DeserializeObject(postData);

            foreach (var ch in dynJson.Children())
            {
                Console.WriteLine(ch);
            }

        }, context);
    }
});

Thread.Sleep(1000);
WebClient web = new WebClient();
web.UploadString("http://localhost:8080", 
                  JsonConvert.SerializeObject(new { ID=1,Name="name1" } ));
L.B
  • 114,136
  • 19
  • 178
  • 224
0

If it is a .Net 4.0 WCF project then JSON is supported directly:

http://msdn.microsoft.com/en-us/library/ee354381.aspx

Locate section "Message Format Selection". Just make sure Accept header is set to application/json

Quintium
  • 499
  • 5
  • 22
  • Please explain downgrade. This makes WCF REST service accept and handle JSON. If I misunderstood the question, then please clarify. – Quintium Jun 19 '12 at 21:48
  • The question is asking how to accept JSON that is in a different format from each client. If all clients posted JSON in the same format, yes the simple built-in support would work. – Jon-Eric Jun 19 '12 at 21:51
  • Thank you. Missed the issue that he can't do it with a C# class (not related to how the clients are passing it, which seems to be the same.) Then yes, my answer is not the correct. Just seems weird it can't be used. – Quintium Jun 19 '12 at 22:03
  • The situation was clearer before the question was edited. It used to state "The issue is that we want to use a single service method for multiple JSON models, so the same service method may accept different JSON structures then within the code under the service we determine the data model being used and process accordingly." – Jon-Eric Jun 20 '12 at 15:50