I'm looking for a way to do deserialization from Json to be version dependent using the data within the Json itself.
I'm targeting to use ServiceStack.Text.JsonDeserializer
, but can switch to another library.
For example, I'd like to define a data in JSON for v1.0 to be:
{
version: "1.0"
condition: "A < B"
}
and then, a next version of the data (say 2.0) to be:
{
version: "2.0"
condition: ["A < B", "B = C", "B < 1"]
}
At the end, I want to be able to validate version of the data to know how to deserialize the JSON correctly.
UPDATE:
It looks like there is no any kind of implicit support for version-dependent JSON (de)serialization in known products.
The right solution seems to be to split the task by (de)serializing only version part and then use implicit (de)serializing for the correct type(s).
Gratitudes to everyone who shared knowledge and thoughts on the problem.
What you can do is either the following:
version
field and nothing else.An example (using System.Web.Script.Serialization.JavaScriptSerializer
):
class BaseClass
{
public int version { get; set; }
}
class FirstVersion: BaseClass
{
public string condition { get; set; }
}
class SecondVersion: BaseClass
{
public IEnumerable<string> condition { get; set; }
}
public void Deserialize (string jsonString)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
BaseClass myData = serializer.Deserialize<BaseClass>(jsonString);
switch (myData.version)
{
case 1:
FirstVersion firstVersion = serializer.Deserialize<FirstVersion>(jsonString);
// ...
break;
case 2:
SecondVersion secondVersion = serializer.Deserialize<SecondVersion>(jsonString);
// ...
break;
}
}
As you can see, this code deserializes the data twice - that may be a problem for you if you are working with large data structures. If you want to avoid that at all costs, you either have to give up static typing or modify the data model of your application.
And here is how it looks like with dynamic
:
public void Deserialize (string jsonString)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
dynamic myData = serializer.Deserialize<object>(jsonString);
if (myData ["version"] == 1) {
...
}
}
There is also the option to write your own custom JavaScriptConverter. That is a lot more work, but I'm pretty sure you can achieve what you want and it will look nicer.
Another advice to consider is never to remove properties from your JSON structure. If you need to modify a property, keep the old one and add a new one instead - this way, old code can always read data from newer code. Of course, this can get out of hand pretty quickly if you modify your data structures a lot...
In Java, you could use Google's GSON library, as it has a built-in support for versioning. I haven't looked into it, but it is open source and if it's really important to you, I guess you can port the implementation to a different language.
I suggest that you use json.net is it allows you to add your custom type converts which can be used for versioning.
The problem is not serialization as it will always use the current schema. The problem is when the client uses a different type version that the server that receives the object.
What you need to do is to check the version programatically in your type converter and the convert the value by yourself (in this case convert the string to an array).
Documentation: http://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With