29

I have the following problem which I am unable to solve:

I have different classes which all implement an interface named IProtocol. The are named, for now, SimpleProtocol, ParallelProtocol. I wanted to persist those object so I used JSON.NET and everything works fine. Except when I am trying to deserialize them it works perfectly when I know the type they are supposed to be, for instance:

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

However, I am now in a situation where I want to load the JSON data and get an IProtocol back, but that is, understandably, not allowed by JSON; E.g., something like this does not work:

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

So, looking up the API I found this method signature:

public static Object DeserializeObject(
    string value,
    Type type
)

which looks just like the thing I needed, so trying out by also persisting the type in a string and retrieving it:

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

I get an error that it is impossible to cast a Newtonsoft.Json.Linq.JObject to IProtocol. This is weird and I don't know how to solve this.

It is impossible to pass the Type object in a generic method, so I am basically stuck here. Is there a method to solve this, preferably without using Reflection? It looks to me that this is a perfectly normal use case.

What I can do, but it seems a bit 'dirty' to me, is to create a simple wrapper class which holds an IProtocol instance in it and serialize / deserialize that?

avanwieringen
  • 2,404
  • 3
  • 21
  • 28
  • Are you deserializing a single element or a collection of them? – Roman Mar 02 '13 at 19:20
  • 2
    You might want to take a look at these questions, and see if they help: [Casting interfaces for deserialization in JSON.NET](http://stackoverflow.com/q/5780888/164966), [How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects](http://stackoverflow.com/q/8030538/164966), [Using Json.NET converters to deserialize properties](http://stackoverflow.com/q/2254872/164966). – Roman Mar 02 '13 at 19:26
  • Thanks for your tips, I've read them through, but my solution proved to be different (see below). – avanwieringen Mar 04 '13 at 08:33

1 Answers1

43

It seemed that my initial approach by using this method was correct after all:

public static Object DeserializeObject(
    string value,
    Type type
)

The problem was that I persisted my object type as using MyProtocol.GetType().FullName which resulted in a value following from

Type protocolType = Type.GetType(PersistedTypeString);

to be a Type with null values. However by using MyProtocol.GetType().AssemblyQualifiedName everything works just fine (p.s. this is also included in the docs of Type.GetType())

Here is my code sample:

Type ProtocolType = Type.GetType(MetaData["ProtocolType"]);
var Protocol = JsonConvert.DeserializeObject(Data["Protocol"], 
                                             ProtocolType, 
                                             JsonProtocolPersister.DefaultSettings);
return (IProtocol)Protocol;
Kjartan
  • 18,591
  • 15
  • 71
  • 96
avanwieringen
  • 2,404
  • 3
  • 21
  • 28