Determine type during json deserialize

牧云@^-^@ 提交于 2019-12-09 12:52:05

问题


I'm working on a protocol in which the receiver will receive json messages of certain specified custom types (currently 5, but could be 10-20). I'm struggling to come up with an optimal/fast solution which will automatically deserialize the json and return the correct type of object.

Example:

public class MessageA
{
    public string Message;
} 

public class MessageB
{
    public int value;
}

public class MessageC
{
    public string ValueA;
    public string ValueB;
}

Ideally, the method should be like

 Object Deserialize(string json);

and it will return one of the three message types OR null - in case there was a parsing error/the json didn't match any of the predefined type.

UPDATE: I have control over sender/receiver as well as the protocol design.


回答1:


It would be helpful if the message could specify its type. Otherwise you have to infer it from some property or another.

You could use a message wrapper class when serializing, like this:

public class MessageWrapper<T>
{
    public string MessageType { get { return typeof(T).FullName; } }
    public T Message { get; set; }
}

So if you have a class Name with a First and Last property, you could serialize it like this:

var nameMessage = new MessageWrapper<Name>();
nameMessage.Message = new Name {First="Bob", Last = "Smith"};
var serialized = JsonConvert.SerializeObject(nameMessage);

The serialized JSON is

{"MessageType":"YourAssembly.Name","Message":{"First":"Bob","Last":"Smith"}}

When deserializing, first deserialize the JSON as this type:

public class MessageWrapper
{
    public string MessageType { get; set; }
    public object Message { get; set; }
}

var deserialized = JsonConvert.DeserializeObject<MessageWrapper>(serialized);

Extract the message type from the MessageType property.

var messageType = Type.GetType(deserialized.MessageType);

Now that you know the type, you can deserialize the Message property.

var message = JsonConvert.DeserializeObject(
    Convert.ToString(deserialized.Message), messageType);

message is an object, but you can cast it as Name or whatever class it actually is.




回答2:


Hopefully you are familiar with the factory pattern, you could use factory(s) and include a "Type" property as part of the json, let's call it _t.

You can either parse the json string yourself and find the _t property's value, deserialise it to a dynamic and get jsonObj._t or have a simple class with only a _t field solely to deserialise the json into initially.

Then you can pass this string representing the C# Type to the factory and get a json deserialiser for that Type.

You can then make all of your outgoing and incoming calls add and process the _t parameter respectively, so that new types are easy to add in future, by just adding and registering the serialisers/deserialisers you need for that Type with the factory(s).



来源:https://stackoverflow.com/questions/38679972/determine-type-during-json-deserialize

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!