我遇到过这种(看似常见的)场景,但找不到令人满意的解决方案。也许有人知道:
出于某种原因,我解析 JSON 并允许用户提供比我的类具有的属性更多的键值对。我像这样存储任意的:
class MusterNode
{
// some definite property
public string TypeName { get; set; }
// takes the rest
// see https://www.newtonsoft.com/json/help/html/DeserializeExtensionData.htm
[JsonExtensionData]
private Dictionary<string, JToken> _extparams;
}
如果我反序列化类似的东西
{
"TypeName": "a",
"stuff": 3
}
TypeName 将被设置并且我的 _extparams 包含一个键“stuff”。
出于某种原因,我想将存储的数据应用到另一个(刚刚创建的)对象“obj”(事实上,参数被认为是那个类型名的东西)。 所以我有一个字典和一个对象。有没有一种方法可以在不先序列化字典的情况下“应用”字典?
我不满意的解决方案是这样的:
string json = JsonConvert.SerializeObject(_extparams);
JsonConvert.PopulateObject(json, obj);
用一些 JsonSerializerSettings 装饰,这对我有用。但它做了不必要的工作。
最佳答案
Json.Net 没有直接从标准字典填充对象的方法。毕竟是序列化库,不是映射库。也就是说,有一种方法可以让它在没有中间序列化/反序列化步骤的情况下工作。
首先,不使用 Dictionary<string, JToken>
作为您的 [JsonExtensionData]
的容器参数,使用 JObject
. JObject
工具 IDictionary<string, JToken>
,所以它仍然可以捕获额外的属性。
class MusterNode
{
...
[JsonExtensionData]
private JObject _extparams;
}
然后,要填充其他对象,您只需从 JObject
创建一个读取器并将其传递给 JsonSerializer.Populate()
像这样:
new JsonSerializer().Populate(_extparams.CreateReader(), obj);
如果您需要特定的序列化设置,可以直接在 JsonSerializer
上进行设置在打电话之前 Populate()
.
这是一个工作演示:https://dotnetfiddle.net/kIzc5G
关于c# - 如何使用 JSON.Net 将 JsonExtensionData (Dictionary<string, JToken>) 应用于另一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52792214/