web-dev-qa-db-fra.com

JSON.NET désérialiser en objet avec le paramètre Type

J'ai le problème suivant que je n'arrive pas à résoudre:

J'ai différentes classes qui implémentent toutes une interface nommée IProtocol. Les sont nommés, pour l'instant, SimpleProtocol, ParallelProtocol. Je voulais conserver ces objets, j'ai donc utilisé JSON.NET et tout fonctionne bien. Sauf lorsque j'essaie de les désérialiser, cela fonctionne parfaitement quand je connais le type qu'ils sont censés être, par exemple:

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

Cependant, je suis maintenant dans une situation où je veux charger les données JSON et récupérer un IProtocol, mais cela n'est, naturellement, pas autorisé par JSON; Par exemple, quelque chose comme ça ne fonctionne pas :

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

Donc, en recherchant API j'ai trouvé cette signature de méthode:

public static Object DeserializeObject(
    string value,
    Type type
)

qui ressemble à ce dont j'avais besoin, donc essayez en persistant également le type dans une chaîne et en le récupérant:

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

Je reçois une erreur indiquant qu'il est impossible de lancer un Newtonsoft.Json.Linq.JObject à IProtocol. C'est bizarre et je ne sais pas comment résoudre ça.

Il est impossible de passer l'objet Type dans une méthode générique, donc je suis fondamentalement coincé ici. Existe-t-il une méthode pour résoudre ce problème, de préférence sans utiliser la réflexion? Il me semble qu'il s'agit d'un cas d'utilisation parfaitement normal.

Ce que je peux faire, mais cela me semble un peu "sale", est de créer une classe wrapper simple qui contient une instance IProtocol et de sérialiser/désérialiser cela?

24
avanwieringen

Il semblait que mon approche initiale en utilisant cette méthode était correcte après tout:

public static Object DeserializeObject(
    string value,
    Type type
)

Le problème était que j'ai persisté mon type d'objet en utilisant MyProtocol.GetType().FullName ce qui a entraîné une valeur suivant

Type protocolType = Type.GetType(PersistedTypeString);

être un type avec des valeurs null. Cependant, en utilisant MyProtocol.GetType().AssemblyQualifiedName tout fonctionne très bien (p.s. cela est également inclus dans les documents de Type.GetType ())

Voici mon exemple de code:

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