What is the best way to handle versioning using JSON protocol?

前端 未结 4 1877
栀梦
栀梦 2020-12-23 16:38

I am normally writing all parts of the code in C# and when writing protocols that are serialized I use FastSerializer that serializes/deserializes the classes fast and effic

4条回答
  •  不思量自难忘°
    2020-12-23 17:12

    Don't use DataContractJsonSerializer, as the name says, the objects that are processed through this class will have to:

    a) Be marked with [DataContract] and [DataMember] attributes.

    b) Be strictly compliant with the defined "Contract" that is, nothing less and nothing more that it is defined. Any extra or missing [DataMember] will make the deserialization to throw an exception.

    If you want to be flexible enough, then use the JavaScriptSerializer if you want to go for the cheap option... or use this library:

    http://json.codeplex.com/

    This will give you enough control over your JSON serialization.

    Imagine you have an object in its early days.

    public class Customer
    { 
        public string Name;
    
        public string LastName;
    }
    

    Once serialized it will look like this:

    { Name: "John", LastName: "Doe" }

    If you change your object definition to add / remove fields. The deserialization will occur smoothly if you use, for example, JavaScriptSerializer.

    public class Customer
    { 
        public string Name;
    
        public string LastName;
    
        public int Age;
    }
    

    If yo try to de-serialize the last json to this new class, no error will be thrown. The thing is that your new fields will be set to their defaults. In this example: "Age" will be set to zero.

    You can include, in your own conventions, a field present in all your objects, that contains the version number. In this case you can tell the difference between an empty field or a version inconsistence.

    So lets say: You have your class Customer v1 serialized:

    { Version: 1, LastName: "Doe", Name: "John" }
    

    You want to deserialize into a Customer v2 instance, you will have:

    { Version: 1, LastName: "Doe", Name: "John", Age: 0}
    

    You can somehow, detect what fields in your object are somehow reliable and what's not. In this case you know that your v2 object instance is coming from a v1 object instance, so the field Age should not be trusted.

    I have in mind that you should use also a custom attribute, e.g. "MinVersion", and mark each field with the minimum supported version number, so you get something like this:

    public class Customer
    { 
        [MinVersion(1)]
        public int Version;
    
        [MinVersion(1)]
        public string Name;
    
        [MinVersion(1)]
        public string LastName;
    
        [MinVersion(2)]
        public int Age;
    }
    

    Then later you can access this meta-data and do whatever you might need with that.

提交回复
热议问题