C# JSON.NET 反序列化为带有 Type 参数的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15178323/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JSON.NET deserialize to object with Type parameter
提问by avanwieringen
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:
我有不同的类,它们都实现了一个名为IProtocol
. 目前,它们被命名为SimpleProtocol
、ParallelProtocol
。我想保留这些对象,所以我使用了 JSON.NET 并且一切正常。除了当我试图反序列化它们时,当我知道它们应该是什么类型时,它可以完美地工作,例如:
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 notwork:
但是,我现在处于一种情况,我想加载 JSON 数据并IProtocol
返回,但可以理解的是,JSON 不允许;例如,这样的事情并没有工作:
IProtocol p1 = JsonConvert.DeserializeObject<IProtocol>(myJsonData); // does not work
IProtocol p2 = (IProtocol)JsonConvert.DeserializeObject(myJsonData); // also, does not work
So, looking up the APII found this method signature:
所以,查找API我发现了这个方法签名:
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.
我收到一个错误,无法将 a 转换Newtonsoft.Json.Linq.JObject
为IProtocol
. 这很奇怪,我不知道如何解决这个问题。
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.
在泛型方法中传递Type对象是不可能的,所以我基本上卡在这里了。有没有办法解决这个问题,最好不使用反射?在我看来,这是一个完全正常的用例。
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?
我能做什么,但对我来说似乎有点“脏”,是创建一个简单的包装类,其中包含一个 IProtocol 实例并序列化/反序列化它?
采纳答案by avanwieringen
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
问题是我坚持使用我的对象类型,MyProtocol.GetType().FullName
这导致了一个值来自
Type protocolType = Type.GetType(PersistedTypeString);
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())
成为具有null
值的类型。然而,通过使用MyProtocol.GetType().AssemblyQualifiedName
一切正常(ps 这也包含在 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;