2016-07-31 2 views
2

Я работаю над протоколом, в котором получатель получит json-сообщения определенных определенных пользовательских типов (в настоящее время 5, но может быть 10-20). Я изо всех сил пытаюсь найти оптимальное/быстрое решение, которое автоматически десериализует json и возвращает правильный тип объекта.Определить тип во время json deserialize

Пример:

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); 

и он будет возвращать один из трех типов сообщений или ноль - в случае, если произошла ошибка синтаксического анализа/The JSON не соответствует никакому предопределенному типу.

UPDATE: У меня есть контроль над отправителем/получателем, а также дизайн протокола.

+0

Вы отправитель, ресивер, или у вас есть контроль над содержимым обоих? – starlight54

ответ

3

Было бы полезно, если сообщение могло указать его тип. В противном случае вы должны сделать это из какого-либо имущества.

Вы можете использовать класс сообщений обертку при сериализации, как это:

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

Так что если у вас есть класс Name со свойством First и Last, вы можете сериализовать это следующим образом:

var nameMessage = new MessageWrapper<Name>(); 
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<MessageWrapper>(serialized); 

Extract тип сообщения от MessageType собственности.

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

Теперь, когда вы знаете тип, вы можете десериализации Message собственности.

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

message является object, но вы можете бросить его как Name или любой другой класс это на самом деле.

0

Надеемся, вы знакомы с заводским рисунком, вы можете использовать фабрику (ы) и включить свойство «Тип» как часть json, назовем его _t.

Вы можете либо разобрать строку JSON себя и найти ценность _t имущества, в deserialise его к dynamic и получить jsonObj._t или имеют простую class с только _t поле исключительно deserialise в JSON в первоначально.

Затем вы можете передать этот string, представляющий тип C#, на заводе и получить десериализатор json для этого Type.

Вы можете сделать все исходящие и входящие вызовы добавить и обработать параметр _t соответственно, так что новые типы легко добавлять в будущем, просто добавив и регистрации serialisers/deserialisers вам нужно для этого Type с завод (ы).

Смежные вопросы