2013-03-02 12 views
17

Mam następujący problem, który jestem w stanie rozwiązać:JSON.NET Cofnięcie sprzeciwu z parametrem Type

mam różne klasy które implementują interfejs o nazwie IProtocol. Na razie są nazywane SimpleProtocol, ParallelProtocol. Chciałem utrzymywać ten obiekt, więc użyłem JSON.NET i wszystko działa dobrze. Z wyjątkiem gdy próbuję deserializowania nich działa idealnie, kiedy wiem, typ one mają być, na przykład:

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

Jednak teraz jestem w sytuacji, gdy chcę załadować dane JSON i uzyskać z powrotem, ale to zrozumiałe, nie jest dozwolone przez JSON; Na przykład coś takiego robi nie praca:

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

Więc patrząc na API znalazłem tej metody Podpis:

public static Object DeserializeObject(
    string value, 
    Type type 
) 

który wygląda jak coś mi potrzebne, więc wypróbowanie przez również utrzymująca typ w ciąg i zdobycie go:

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

pojawia się błąd, że jest niemożliwe, aby rzucić Newtonsoft.Json.Linq.JObject do IProtocol. To dziwne i nie wiem, jak to rozwiązać.

Nie można przekazać obiektu typu metodą ogólną, więc utknąłem tutaj. Czy istnieje metoda rozwiązania tego problemu, najlepiej bez użycia refleksji? Wydaje mi się, że jest to całkowicie normalny przypadek użycia.

Co mogę zrobić, ale wydaje mi się to trochę "brudne", to stworzyć prostą klasę opakowania, która zawiera instancję IProtocol i serializować/deserializować?

+0

Czy deserializacji pojedynczy element lub zbiór im? – R0MANARMY

+2

Możesz rzucić okiem na te pytania i sprawdzić, czy pomagają one: [Casting interfaces do deserializacji w JSON.NET] (http://stackoverflow.com/q/5780888/164966), [Jak zaimplementować niestandardowy JsonConverter w JSON.NET w celu deserializacji listy obiektów klasy bazowej] (http://stackoverflow.com/q/8030538/164966), [Używanie konwerterów Json.NET do deserializacji właściwości] (http://stackoverflow.com/q/ 2254872/164966). – R0MANARMY

+0

Dzięki za porady, przeczytałem je, ale moje rozwiązanie okazało się inne (patrz poniżej). – avanwieringen

Odpowiedz

22

Wydawało się, że moje pierwsze podejście przy użyciu tej metody była prawidłowa po wszystkim:

public static Object DeserializeObject(
    string value, 
    Type type 
) 

Problemem było to, że utrzymywał mój obiekt typu jak użycie MyProtocol.GetType().FullName które doprowadziły do ​​wartości wynikających z

Type protocolType = Type.GetType(PersistedTypeString);

na wartość typu z wartościami null. Jednak za pomocą MyProtocol.GetType().AssemblyQualifiedName wszystko działa dobrze (ps ten jest również w docs Type.GetType())

Oto mój przykładowy kod:

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