gpt4 book ai didi

c# - Json.NET 反序列化或序列化 json 字符串并将属性映射到运行时定义的不同属性名称

转载 作者:太空狗 更新时间:2023-10-29 17:47:45 25 4
gpt4 key购买 nike

我有以下 JSON 字符串:

{
"values": {
"details": {
"property1": "94",
"property2": "47",
"property3": "32",
"property4": 1
},
count: 4
}
}

我要将其映射到以下模型:

public class Details
{
public string property1 { get; set; }
public string property2 { get; set; }
public string property3 { get; set; }
public int property4 { get; set; }
}

public class Values
{
public Details details { get; set; }
public int count { get; set; }
}

public class RootObject
{
public Values values { get; set; }
}

在反序列化此 JSON 字符串时,我希望能够在运行时将这些属性名称映射到不同的名称:

JsonConvert.DeserializeObject<RootObject>(jsonString);

例如,在反序列化过程中,我希望将“property1”的名称反序列化为“differen_property_name1”或“differen_property_name2”或“differen_property_name3”。因为我在运行时选择新名称(我将“property1”名称更改为的新名称),所以我无法使用使用 JsonPropertyAttribute 的解决方案,如此处建议:

.NET NewtonSoft JSON deserialize map to a different property name

上述问题的答案之一(Jack 的答案)使用了 DefaultContractResolver 的继承,但在那种情况下它似乎不起作用。

更新

稍后,我需要序列化从反序列化中获得的对象,并将属性映射到在运行时定义的不同属性名称。我使用与 Brian 提议的方法相同的方法来进行序列化:

我使用字典来映射我的新属性名称:

var map = new Dictionary<Type, Dictionary<string, string>>
{
{
typeof(Details),
new Dictionary<string, string>
{
{"property1", "myNewPropertyName1"},
{"property2", "myNewPropertyName2"},
{"property3", "myNewPropertyName3"},
{"property4", "myNewPropertyName4"}
}
}
};

然后我使用 Brian 的 DynamicMappingResolver 像这样序列化对象:

var settings = new JsonSerializerSettings
{
ContractResolver = new DynamicMappingResolver(map)
};

var root = JsonConvert.SerializeObject(myObjectInstance, settings);

最佳答案

您可以使用自定义 ContractResolver去做这个。基本上这与放置 [JsonProperty] 相同。您要为其映射到不同 JSON 属性名称的每个类成员的属性,除非您通过解析器以编程方式执行此操作。在反序列化之前设置时,您可以将所需映射的字典传递给解析器。

自定义解析器代码可能如下所示:

class DynamicMappingResolver : DefaultContractResolver
{
private Dictionary<Type, Dictionary<string, string>> memberNameToJsonNameMap;

public DynamicMappingResolver(Dictionary<Type, Dictionary<string, string>> memberNameToJsonNameMap)
{
this.memberNameToJsonNameMap = memberNameToJsonNameMap;
}

protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
Dictionary<string, string> dict;
string jsonName;
if (memberNameToJsonNameMap.TryGetValue(member.DeclaringType, out dict) &&
dict.TryGetValue(member.Name, out jsonName))
{
prop.PropertyName = jsonName;
}
return prop;
}
}

要使用解析器,首先构造一个 Dictionary<Type, Dictionary<string, string>>包含您的映射。外部字典的键是您要映射其属性的类类型;内部字典是类属性名称到 JSON 属性名称的映射。您只需为其名称尚未与 JSON 匹配的属性提供映射。

因此,例如,如果您的 JSON 看起来像这样(请注意 details 对象中属性的更改名称)...

{
"values": {
"details": {
"foo": "94",
"bar": "47",
"baz": "32",
"quux": 1
},
count: 4
}
}

...并且您想将其映射到问题中的类,您可以像这样创建字典:

var map = new Dictionary<Type, Dictionary<string, string>>
{
{
typeof(Details),
new Dictionary<string, string>
{
{"property1", "foo"},
{"property2", "bar"},
{"property3", "baz"},
{"property4", "quux"}
}
}
};

最后一步是用一个新的解析器实例设置序列化器设置,给它你刚刚构建的映射字典,然后将设置传递给JsonConvert.DeserializeObject()。 .

var settings = new JsonSerializerSettings
{
ContractResolver = new DynamicMappingResolver(map)
};

var root = JsonConvert.DeserializeObject<RootObject>(json, settings);

这是一个演示:https://dotnetfiddle.net/ULkB0J

关于c# - Json.NET 反序列化或序列化 json 字符串并将属性映射到运行时定义的不同属性名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38111298/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com