2016-07-31 30 views
2

Ich arbeite an einem Protokoll, in dem der Empfänger Json-Nachrichten bestimmter bestimmter benutzerdefinierten Typen (derzeit 5, könnte aber 10-20 sein). Ich habe Mühe, eine optimale/schnelle Lösung zu finden, die den JSON automatisch deserialisiert und den richtigen Objekttyp zurückgibt.Ermitteln Sie den Typ während Json deserialize

Beispiel:

public class MessageA 
{ 
    public string Message; 
} 

public class MessageB 
{ 
    public int value; 
} 

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

Idealerweise sollte das Verfahren sein, wie

Object Deserialize(string json); 

und es wird eine der drei Nachrichtentypen oder null zurück - falls es ein Parsingfehler war/die json hat keinen der vordefinierten Typen gefunden.

UPDATE: Ich habe Kontrolle über Sender/Empfänger sowie das Protokoll Design.

+0

Sind Sie der Absender, Empfänger oder haben Sie die Kontrolle über den Inhalt von beiden? – starlight54

Antwort

3

Es wäre hilfreich, wenn die Nachricht ihren Typ angeben könnte. Ansonsten müssen Sie es von einer Eigenschaft oder einer anderen schließen.

Sie könnten eine Nachricht Wrapper-Klasse verwenden, wenn die Serialisierung, wie folgt aus:

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

Also, wenn Sie eine Klasse Name mit einem First und Last Eigenschaft haben, können Sie es wie folgt serialisiert:

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

Die serialisierten JSON ist

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

Wenn Deserialisieren zuerst die JSON als diese Art deserialisieren:

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

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

den Nachrichtentyp aus der MessageType Eigenschaft extrahieren.

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

Nachdem Sie nun den Typ kennen, können Sie die Message Eigenschaft deserialisieren.

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

message ist ein object, aber man kann es als Name werfen oder was auch immer Klasse es tatsächlich ist.

0

Hoffentlich sind Sie vertraut mit dem Fabrikmuster, Sie könnten Fabrik (en) verwenden und eine "Type" -Eigenschaft als Teil des JSON aufnehmen, nennen wir es _t.

können Sie entweder analysieren die JSON-String selbst und finden Sie den Wert des _t Eigenschaft, deserialise es zu einem dynamic und bekommen jsonObj._t oder haben eine einfache class mit nur einem _t Feld allein die json in zunächst auf deserialise.

Dann können Sie diese string, die den C# -Typ darstellt, an die Fabrik übergeben und einen JSON-Deserialiser für diesen Type bekommen.

Sie können dann machen alle Ihre ausgehenden und eingehenden Anrufe hinzufügen und bearbeiten die _t Parameter jeweils so, dass neue Arten sind leicht in Zukunft hinzuzufügen, indem Sie gerade hinzufügen und die Serializer Registrierung/Deserializer Sie, dass Type müssen, um mit der Fabrik (en).