在json反序列化期间确定类型

我正在研究一种协议,其中接收器将接收某些指定自定义类型的json消息(当前为5,但可能为10-20)。 我正在努力想出一个最优/快速的解决方案,它将自动反序列化json并返回正确类型的对象。

例:

public class MessageA { public string Message; } public class MessageB { public int value; } public class MessageC { public string ValueA; public string ValueB; } 

理想情况下,该方法应该是这样的

  Object Deserialize(string json); 

并且它将返回三种消息类型之一或null – 如果存在解析错误/ json与任何预定义类型都不匹配。

更新:我可以控制发送器/接收器以及协议设计。

如果消息可以指定其类型,将会很有帮助。 否则你必须从某个财产或其他财产推断它。

您可以在序列化时使用消息包装类,如下所示:

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

因此,如果您有一个具有FirstLast属性的类Name ,您可以像这样序列化它:

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

序列化的JSON是

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

反序列化时,首先将JSON反序列化为此类型:

 public class MessageWrapper { public string MessageType { get; set; } public object Message { get; set; } } var deserialized = JsonConvert.DeserializeObject(serialized); 

MessageType属性中提取消息类型。

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

既然知道了类型,就可以反序列化Message属性。

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

message是一个object ,但您可以将其强制转换为Name或其实际所在的类。

希望您熟悉工厂模式,您可以使用工厂并将“Type”属性作为json的一部分包含在内,让我们称之为_t

您可以自己解析json字符串并找到_t属性的值,将其反序列化为dynamic并获取jsonObj._t或者只有一个只有_t字段的简单class ,以便最初将json反序列化。

然后,您可以将表示C#Type的string传递给工厂,并为该Type获取json反序列化器。

然后,您可以分别对所有传出和传入呼叫添加和处理_t参数,以便将来很容易添加新类型,只需添加并注册该Type与工厂所需的序列化器/反序列化器。