tags:

views:

900

answers:

1

We have SOAP implementations of our services and up till now we had some legacy code that was wrapping our args and returns in another object to get around some serialization / generics on RPC methods.

After optimization, we had implemented this class so that it Json serialized (DataContractJsonSerializer) and GZipped our complex request params and response objects.

I now want to push this stuff down into the WCF stack. What I really want is the ability to encode the message body as GZipped Json on a standard SOAP service. We need transactional support and security etc so we need to be able to support the standard bindings.

I have managed to implement an Operation Behavior to Json serialize so that the message infoset will contain json compatible XML. I then wanted to add a MessageEncoder to turn the xml into json in the message body. This is where I have issues. I can't serialize the whole message as we still have standard soap headers etc and the s:body still contains a root Request or Response object before the json compatible xml. I figure I can use the JsonReaderWriterFactory just not sure how to apply to the correc portion of the message.

I know I can do the GZIP later if I can just figure out reading and writing this Json section.

Any ideas? Pete

OK. So some clarification.

My service looks like this

[ServiceContract]
public interface IMyService {
  [OperationContract]
  Person SavePerson(Person personToSave);

  [OperationContract]
  Person GetPersons();
}

and the output from the GetPersons() method would look something like this:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"&gt;
  <s:Header>
    <a:Action s:mustUnderstand="1">http://www.petegoo.com/wcf/MyService/IMyService/GetPersonsResponse&lt;/a:Action&gt;
    <a:RelatesTo>urn:uuid:a18ccf1c-0793-4240-ba6f-9e86b6f2fdf6</a:RelatesTo>
  </s:Header>
  <s:Body>[{"DateOfBirth":"\/Date(286801200000+1300)\/","FirstName":"Foo","Id":1,"LastName":"Bar"},{"DateOfBirth":"\/Date(333720000000+1200)\/","FirstName":"Foo","Id":1,"LastName":"Bar"}]</s:Body>
</s:Envelope>

Note: The above was ad hoc so may not be syntactically or semantically correct.

A: 

My understanding is you like embed JSON into XML infoset in the SOAP? It'd be easier to write some sample request and response that you want to achieve.

I don't see a good reason to coexist JSON infoset with XML infoset. However you can return JSON data as a string value of a XML element/attribute in the SOAP.

codemeit
I should have elaborated, we had optimized our message for on-the-wire size to JSON+GZip. That is my reason for wanting to keep this format. I'd be happy enough at the moment to separate to just JSON, I can add the compression later as there are plenty of examples. As for a string value in the xml as an attribute or element, I still want to have an explicit service contract. I would like to be able to swap it all out using just config. If it can be buried in the WCF stack like this then great but not sure how.
If you really care about the size of the message, you can make the whole service return pure JSON, however, you wouldn't have the features supported in your soap header. By seeing the output from the GetPersons(), I've no idea how the WSDL should look like for mixed JSON and XML. If you really want to do this, I still think put the whole JSON as a string value of the SOAP response.
codemeit
Have you any idea how I would put the JSON as a string value of the SOAP Response without changing the contract in code. In other words what are the WCF extensibility points to make this happen?
This is the only way I can think of,[DataContract]public class Person{ // existing properties go here public string PersonJosnString {get;set;}}
codemeit
Thanks. That's not really going to work for me. I don't want to pollute the data contract with implementation detail. I would rather bury it in the WCF stack so that I don't have this requirement on the data. Thanks for you help though.
I think you don't have to manually populate that property each time for each datacontract object, in the wcf stack, you could implement something to populate, say IJosnable object, in IJsonable, it defines the JosnString field which storing the Json representation of current datacontract object. Anyway, keep me updated how you go forward. thanks.
codemeit