JSON.NET десериализует объект с параметром Type
У меня есть следующая проблема, которую я не могу решить:
У меня есть разные классы, которые реализуют интерфейс с именем IProtocol
. На данный момент они называются SimpleProtocol
, ParallelProtocol
. Я хотел сохранить этот объект, поэтому использовал JSON.NET, и все работает нормально. За исключением случаев, когда я пытаюсь их десериализовать, он отлично работает, когда я знаю тип, которым они должны быть, например:
SimpleProtocol p = JsonConvert.DeserializeObject<SimpleProtocol>(myJsonData);
Однако теперь я в ситуации, когда хочу загрузить данные JSON и получить IProtocol
назад, но это, понятно, не разрешено JSON; Например, что-то вроде этого работает не:
IProtocol p1 = JsonConvert.DeserializeObject<IProtocol>(myJsonData); // does not work
IProtocol p2 = (IProtocol)JsonConvert.DeserializeObject(myJsonData); // also, does not work
Итак, посмотрев API, я нашел эту подпись метода:
public static Object DeserializeObject(
string value,
Type type
)
который выглядит так же, как и то, что мне нужно, поэтому попробуйте, сохранив тип в строке и получив его:
// test
Type protocolType = Type.GetType("MyApp.Protocols.SimpleProtocol");
IProtocol p1 = JsonConvert.DeserializeObject(myJsonData, protocolType);
Я получаю сообщение об ошибке, что невозможно отбросить Newtonsoft.Json.Linq.JObject
до IProtocol
. Это странно, и я не знаю, как это решить.
Нельзя передать объект Type в общий метод, поэтому я в основном застрял здесь. Есть ли способ решить эту проблему, желательно без использования Reflection? Мне кажется, что это совершенно нормальный вариант использования.
Что я могу сделать, но для меня это немного "грязно", это создать простой класс-оболочку, который содержит в себе экземпляр IProtocol и сериализует/десериализует это?
Ответы
Ответ 1
Казалось, что мой первоначальный подход с использованием этого метода был прав в конце концов:
public static Object DeserializeObject(
string value,
Type type
)
Проблема заключалась в том, что я сохранил свой тип объекта, используя MyProtocol.GetType().FullName
, в результате чего получилось значение, следующее из
Type protocolType = Type.GetType(PersistedTypeString);
- тип с null
. Однако, используя MyProtocol.GetType().AssemblyQualifiedName
, все работает просто отлично (p.s. это также включено в документы Type.GetType())
Вот мой пример кода:
Type ProtocolType = Type.GetType(MetaData["ProtocolType"]);
var Protocol = JsonConvert.DeserializeObject(Data["Protocol"],
ProtocolType,
JsonProtocolPersister.DefaultSettings);
return (IProtocol)Protocol;