gpt4 book ai didi

c# - 将成员序列化为 Object 或 List
转载 作者:太空宇宙 更新时间:2023-11-03 10:51:23 28 4
gpt4 key购买 nike

这有点类似于JSON.net - field is either string or List

假设我有以下 POCO 类,需要将 json 字符串反序列化为该类型。

public class Movie 
{
[JsonProperty("title")]
public List<string> Title { get; set; }

[JsonProperty("images")]
public List<Image> Images { get; set; }

[JsonProperty("actors")]
public List<Actor> Actors { get; set; }

[JsonProperty("directors")]
public List<Director> Directors { get; set; }
}

假设需要反序列化的json字符串如下

{
"title": "Movie title",
"images": [
{"url" : "http://www.url.com/img_3.jpg"},
{"url" : "http://www.url.com/img_4.jpg"}
],
"actors": [
{"name" : "Steven Berkoff"},
{"name" : "Nikolaj Coster-Waldau"},
{"name" : "Julie Cox"}
],
"directors": { "name" : "Simon Aeby" }
},
{
"title": "Movie title",
"images": {"url" : "http://www.url.com/img_3.jpg"},
"actors": {"name" : "Julie Cox"},
"directors": { "name" : "Simon Aeby" }
}

这里的问题甚至认为 POCO 需要一个导演、 Actor 和图像列表,json 只有一种类型。尝试反序列化时出错。

最佳答案

为那些可以识别列表中是否有一个或多个项目并将其应用于您的属性的列表创建一个转换器:

public class SingleOrEnumerableJsonConverter<TEnumerable> : JsonConverter
where TEnumerable : IEnumerable
{
public override bool CanConvert(Type objectType)
{
return typeof(TEnumerable).IsAssignableFrom(objectType);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var obj = serializer.Deserialize<JToken>(reader);
return ConvertObject(obj) ?? GetDefaultValue();
}

private object GetDefaultValue()
{
return Activator.CreateInstance<TEnumerable>();
}

private object ConvertObject(JToken obj)
{
try
{
return obj.ToObject<TEnumerable>();
}
catch (JsonSerializationException)
{
// try as an array of object
return new JArray { obj }.ToObject<TEnumerable>();
}
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
object serializableValue = GetSerializableValue((TEnumerable)value, serializer);
serializer.Serialize(writer, serializableValue);
}

private object GetSerializableValue(TEnumerable items, JsonSerializer serializer)
{
var arr = new JArray(items.Cast<object>()
.Select(item => JToken.FromObject(item, serializer))
);
return arr.Count > 1 ? arr : arr.SingleOrDefault();
}
}
public class Movie 
{
[JsonProperty("title")]
[JsonConverter(typeof(SingleOrEnumerableJsonConverter<List<string>>))]
public List<string> Title { get; set; }

[JsonProperty("images")]
[JsonConverter(typeof(SingleOrEnumerableJsonConverter<List<Image>>))]
public List<Image> Images { get; set; }

[JsonProperty("actors")]
[JsonConverter(typeof(SingleOrEnumerableJsonConverter<List<Actor>>))]
public List<Actor> Actors { get; set; }

[JsonProperty("directors")]
[JsonConverter(typeof(SingleOrEnumerableJsonConverter<List<Director>>))]
public List<Director> Directors { get; set; }
}

关于c# - 将成员序列化为 Object 或 List<Object>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21301805/

28 4 0