gpt4 book ai didi

c# - 自定义反序列化器仅适用于 json.NET 的某些字段

转载 作者:太空狗 更新时间:2023-10-29 17:50:23 27 4
gpt4 key购买 nike

我正在尝试反序列化一些 JSON:

{ 
"a":1,
"b":25,
"c":"1-7",
"obj1":{
"a1":10,
"b1":45,
"c1":60
},
"obj2":[
{
"a2":100,
"b2":15,
"c2":50
},
{
"e2":"1,2,5-7",
"f2":"1,3-5",
"a2":25
}
]
}

我想找到一种方法来为某些字段定义自定义反序列化。

在下面的代码中,我将需要注意的字段(自定义处理)与可以以某种方式自动完成的字段分开。

是否可以自动反序列化“正常”字段? (不需要任何特定的自定义处理)

[JsonConverter(typeof(ConfigurationSerializer))]
public class Configuration
{
public int a { get; set; }
public int b { get; set; }
public Obj1 obj1 { get; set; }

public int[] c { get; set; }
public IList<Obj2> obj2 { get; set; }
}

public class ConfigurationSerializer : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jsonObject = JObject.Load(reader);

Configuration configuration = new Configuration();

// I would like this part to be automatic as I just repeat the default
// In the real case, I have many fields here!
configuration.a = (int)jsonObject["a"];
configuration.b = (int)jsonObject["b"];
configuration.obj1 = jsonObject["obj1"].ToObject<Obj1>();

// I created the JsonConverter for those 2 properties
configuration.c = myCustomProcessMethod(jsonObject["c"]);
configuration.obj2 = myCustomProcessMethod2(jsonObject["obj2"].ToObject<ValletConfiguration>());

return configuration;
}

public override bool CanConvert(Type objectType)
{
return typeof(Configuration).IsAssignableFrom(objectType);
}
}

最佳答案

由于无论如何您都在使用 Json.NET 属性注释您的类型,因此更简单的解决方案似乎是使用 [JsonConverter(Type)] 将转换器放在相关属性上。或 [JsonProperty(ItemConverterType = Type)] :

public class Configuration
{
public int a { get; set; }
public int b { get; set; }
public Obj1 obj1 { get; set; }

// Converts the entire list to a compressed string
[JsonConverter(typeof(IntListConverter))]
public int[] c { get; set; }

// Converts each Obj2 item individually
[JsonProperty(ItemConverterType = typeof(Obj2Converter))]
public IList<Obj2> obj2 { get; set; }
}

然而,如果您需要在 Configuration 上保留转换器(或者实际上是将转换器添加到 JsonSerializerSettings.Converters 并且不能将 Json.NET 属性添加到您的类型),您可以使用 JsonSerializer.Populate()填充标准属性,只要您首先从 JObject 中删除自定义属性:

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;

var jsonObject = JObject.Load(reader);

var configuration = (existingValue as Configuration ?? new Configuration());

// I created the JsonConverter for those 2 properties
configuration.c = myCustomProcessMethod(jsonObject["c"].RemoveFromLowestPossibleParent());
configuration.obj2 = myCustomProcessMethod2(jsonObject["obj2"].RemoveFromLowestPossibleParent().ToObject<ValletConfiguration>());

// Populate the remaining standard properties
using (var subReader = jsonObject.CreateReader())
{
serializer.Populate(subReader, configuration);
}

return configuration;
}

使用扩展方法:

public static class JsonExtensions
{
public static JToken RemoveFromLowestPossibleParent(this JToken node)
{
if (node == null)
return null;
var contained = node.AncestorsAndSelf().Where(t => t.Parent is JContainer && t.Parent.Type != JTokenType.Property).FirstOrDefault();
if (contained != null)
contained.Remove();
// Also detach the node from its immediate containing property -- Remove() does not do this even though it seems like it should
if (node.Parent is JProperty)
((JProperty)node.Parent).Value = null;
return node;
}
}

关于c# - 自定义反序列化器仅适用于 json.NET 的某些字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41510242/

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