JsConfig.DeSerializeFn / RawDeserializeFn not called for parameters in querystring

HI,
I’ve an operation gettting as input and returning as output dates (Datetime in C#).

I set JsConfig.DateHandler = DateHandler.RFC1123; and JsConfig.SerializeFn and JsConfig.DeSerializeFn on both client (usimng ServiceStack.HttpClient) and server.

Problem: If I call the method as a GET the date goes to the querystring. : SerializeFn is corerctly called on the client side BUT DeSerializeFn is not called on the server side (it is called if I make a POST call to the same operation).

Is it a bug ? or should I set the DeSerializeFn on something else ?

B.T.W. : what is the difference between SerializeFn /DESerializeFn and their raw counterpart ?

thank you
Enrico

If you set any of the Serialize/Deserialize callbacks than you’re taking over the serialization/deserialization of DateTimes so if you override the Serialization you should also deserialize the Deserialization as well.

Do you have a complete example that doesn’t work? i.e. including any JsConfig.

Difference between SerializeFn and RawSerializeFn is that SerializeFn gets escaped as a JSON string whilst RawSerializeFn doesn’t.

you can find a sample here : (see the unit test)

I noticed another “strange” thing … : if i remove the deserialize/serialize hooks and i specify a dateformat using jsonconfig …
this setting is ignored when serializing a date that goes to querystring. (it’s Always yyyy-mm-dd … etc … ).

I understand that a querystring is not in the JsConfig. world … but on the client side the serailization funztion is called for the date paraemter that will go to querystring , so it should be called when deserializing as well

let me know
thank you
enrico

This project doesn’t build, it’s missing files in: https://github.com/sabbadino/d3sabba/tree/master/SS_ASPNET_01/SS_ASPNET_01/SS_ASPNET_01.ServiceModel

But I just need a simple stand-alone test I can run, like the one I’ve created for this here.

Serialization/Deserialization is working fine, but you need to use JsConfig<DateTime>.SerializeFn since the DateTime is not a native JSON value so needs to be quoted, (unless you want to do the quoting yourself).

Note: Taking over deserialization means the JSON Serializer is no longer flexible in parsing different date formats, as you’ll need to handle them yourself.

Now the solution SS_ASPNET_01.sln will compile.
put a break point below the line
// THIS IS NOT CALLED WHEN DOING A GET TO FindDate (date is in querystring)

in apphost.cs

	JsConfig<DateTime>.DeSerializeFn = time =>
				{
					// THIS IS NOT CALLED WHEN DOING A GET TO FindDate (date is in querystring)
					var x = DateTime.ParseExact(time, "o", null);
					return x;
				};

Run the solution and then run in debug mode the only unit test you have in the test project (named TestMethod1).
In that unit test there is a call to the same operation, one with post one with get …

you will see that you have
JsConfig.DeSerializeFn = time =>

called only once (for the post request).

hope I was clear enough
let me know
thank you
enrico

The property caches for the queryString delegates are created when the Services are registered which happen before AppHost.Configure() is called, so you need to register custom serializers before the AppHost is initialized, e.g:

JsConfig<DateTime>.SerializeFn = time =>
{
    var x = new DateTime(time.Ticks, DateTimeKind.Unspecified).ToString("o");
    return x;
};

JsConfig<DateTime>.DeSerializeFn = time =>
{
    var x = DateTime.ParseExact(time, "o", null);
    return x;
};

new AppHost().Init();

Thank you for the info.
Is it a desired behaviour or a bug ?
I’d personally call it a bug , still , the fix would be a breaking change.
Would it make sense to introduce a QueryStringConfig ?

best regards
enrico

Auto wiring the Services and priming the delegate caches is by design.

It might be “by design” , but for sure it doesn’t follow the “Principle of Least Astonishment” (setting serialization /deserialization for anything else by querystring works in host.config, for querystring you need to do it before host.init).

IMHO
enrico