2013-03-02 18 views
17

Ho il seguente problema che non riesco a risolvere:JSON.NET deserialize di opporsi con parametro Type

ho diverse classi che tutto implementare un'interfaccia denominata IProtocol. Si chiamano, per ora, SimpleProtocol, ParallelProtocol. Volevo mantenere quegli oggetti così ho usato JSON.NET e tutto funziona bene. Tranne quando sto cercando di deserializzare loro funziona perfettamente quando so il tipo che si suppone essere, ad esempio:

SimpleProtocol p = JsonConvert.DeserializeObject<SimpleProtocol>(myJsonData); 

Tuttavia, ora sono in una situazione dove voglio caricare i dati JSON e ottenere un IProtocol indietro, ma questo è, comprensibilmente, non consentito da JSON; Ad esempio, una cosa del genere non non lavoro:

IProtocol p1 = JsonConvert.DeserializeObject<IProtocol>(myJsonData); // does not work 
IProtocol p2 = (IProtocol)JsonConvert.DeserializeObject(myJsonData); // also, does not work 

Così, guardando il API ho trovato questo metodo di firma:

public static Object DeserializeObject(
    string value, 
    Type type 
) 

che sembra proprio la cosa di cui avevo bisogno, in modo da provare per anche persistendo tipo in una stringa e il recupero è:

// test 
Type protocolType = Type.GetType("MyApp.Protocols.SimpleProtocol"); 
IProtocol p1 = JsonConvert.DeserializeObject(myJsonData, protocolType); 

ottengo un errore che è impossibile per lanciare unDa 210 a IProtocol. Questo è strano e non so come risolvere questo.

È impossibile passare l'oggetto Type in un metodo generico, quindi in pratica sono bloccato qui. Esiste un metodo per risolvere questo problema, preferibilmente senza usare Reflection? Mi sembra che questo sia un caso d'uso perfettamente normale.

Quello che posso fare, ma a me sembra un po '"sporco", è creare una classe wrapper semplice che contenga un'istanza IProtocollo e la serializzi/deserializzi?

+0

Stai deserializzazione un singolo elemento o un insieme di loro? – R0MANARMY

+2

Puoi dare un'occhiata a queste domande e vedere se aiutano: [Interfaccia di cast per la deserializzazione in JSON.NET] (http://stackoverflow.com/q/5780888/164966), [Come implementare JsonConverter personalizzato in JSON.NET per deserializzare un elenco di oggetti della classe base] (http://stackoverflow.com/q/8030538/164966), [Utilizzo dei convertitori Json.NET per deserializzare le proprietà] (http://stackoverflow.com/q/ 2254872/164966). – R0MANARMY

+0

Grazie per i tuoi suggerimenti, li ho letti, ma la mia soluzione si è rivelata diversa (vedi sotto). – avanwieringen

risposta

22

Sembrava che il mio primo approccio con questo metodo era corretto, dopo tutto:

public static Object DeserializeObject(
    string value, 
    Type type 
) 

Il problema era che ho perseverato il mio tipo di oggetto come utilizzare MyProtocol.GetType().FullName che ha determinato un valore seguito da

Type protocolType = Type.GetType(PersistedTypeString);

essere un tipo con valori null. Tuttavia utilizzando MyProtocol.GetType().AssemblyQualifiedName tutto funziona bene (PS Questo è anche incluso nella documentazione di Type.GetType())

Ecco il mio codice di esempio:

Type ProtocolType = Type.GetType(MetaData["ProtocolType"]); 
var Protocol = JsonConvert.DeserializeObject(Data["Protocol"], 
              ProtocolType, 
              JsonProtocolPersister.DefaultSettings); 
return (IProtocol)Protocol; 
Problemi correlati