Drazen Dotlic - 414 - Aug 20, 2014

Hi,

what would be the simplest way to override result stream deserialization?

A bit of context: in a few cases it’s very beneficial for the server to return compressed result, but ignoring the Accept-Encoding header (because - thanks Microsoft - Silverlight just won’t send something other than ‘identity’ here), which then confuses ServiceStack’s client (again, this is Silverlight client) because it doesn’t expect compressed result and then errors out, so I’d like to take care of decompression myself (doesn’t matter how).

I tried overriding the ServiceClientBase ‘T DeserializeFromStream<T>(Stream stream);’ but this method simply isn’t called (??).

I can see there’s also StreamDeserializer property (overridable) which is a delegate, and am at the moment experimenting with this, but to save myself some time I’d like to know if I’m on a right track or if I should try a different approach. I’d also like to know why two seemingly identical ‘methods’ for deserialization (of which one isn’t called).

Thanks in advance.

Drazen Dotlic:

Just tried replacing StreamDeserializer delegate and my override does get called, so with a bit of luck it’ll all end well, but I’m still not there.

Subclassing ServiceClientBase and overriding the de/serialization methods with your own should all be that’s required - this is what differentiates JsonServiceClient from XmlServiceClient, etc:
https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.Client/JsonServiceClient.cs

Marc-Antoine Latour:

Also if you set EmulateHttpViaPost to True the SS client will then use the browser http stack and compression will work

Drazen Dotlic:

+Demis Bellot I did look into source but did not understand why two methods, which is less important than the fact that DeserializeFromStream method (overriden) does not get called, but the delegate StreamDeserializer is.

Drazen Dotlic:

+Marc-Antoine Latour Good to know, I was trying to figure this out (I knew there had to be a hook somewhere), but potential problem is that browser’s stack does not support cross-domain calls IIRC (which actually matters to us in the debugging scenario).

Drazen Dotlic:

+Demis Bellot I did not state this clearly, but I was subclassing the JsonServiceClient and not ServiceClientBase, along the lines of my question about minimal effort necessary :wink:

Marc-Antoine Latour:

Yes it does support cross-domain call as we are using it with no issue…

But I forgot to say that if you EmulateHttpViaPost you will need to adjust the handling of web service exception since the browser http stack doesn’t support reading a http response that is not of 200 status code

Drazen Dotlic:

+Marc-Antoine Latour Great! Is there any advantage to using the Silverlight’s http stack?? 

Marc-Antoine Latour:

We’ll the major benefit for us is that we can use HttpOnly cookie… Does type of cookie could not be read by script like js, flash or silverlight and our security infrastructure is requiring that to be authenticated…


Marc-Antoine Latour:

But if you’re able to make compression work with the client http, and if HttpOnly cookie is not require I think it is best to stay with the client http since other limitation exists using the browser stack like reading custom header and so on…

Drazen Dotlic:

+Marc-Antoine Latour I did not understand if HttpOnly is or isn’t supported by browser/client http stack? Whose advantage are you using browser’s http stack or client’s?
At the moment, unfortunately, I am unable to make decompression work but not because of ServiceStack, I cannot find a PCL or SL5 compatible library to decompress a stream. Zlib.Portable should work but isn’t compiled correctly and GZipStream tries to instantiate Encoding which doesn’t exist in SL5, though their source code is correct and has a workaround for this (weird). So I’m very close to having client http and compression but not there yet. Thanks for your comments!

Marc-Antoine Latour:

BrowserHttp : 
 - Support Get/POST only
 - Support POST Only for cross-domain call (EmulateHttpViaPost will fix that)
 - Support Compression
 - Support HttpOnly cookie
 - Limitation on request stream
 - Cannot read response other than 200

ClientHttp :
 - Support all HTTP VERB
 - Support reading custom http header
 - Cannot read cookie that are set HttpOnly
 - Support reading any response

Hope that helps 

Marc-Antoine Latour:

and BTW the other method DeserializeFromStream that is not used directly by the SS Client is a Hook that Demis as created for me to help me handle webserviceexception when using the EmulateHttpViaPost option

Drazen Dotlic:

+Marc-Antoine Latour It does help (merci bien!), though it’s unclear which of the two is better based on the above list.
Anyway, after quite a bit of struggling to find a minimal PCL library to decompress GZipped content, I managed to make this work (phew) with SharpZipLib, which is rather old and relatively big (200KB vs ~80KB for Zlib.Portable) but what the hell, will send a pull request to Zlib.Portable maintainer and in the meantime will simply use SharpZipLib.

Cheers!

Marc-Antoine Latour:

Good to know !!

Avec plaisir !