gpt4 book ai didi

c# - 如果不兼容,让 Json.NET 忽略 $type

转载 作者:行者123 更新时间:2023-11-30 16:52:00 24 4
gpt4 key购买 nike

我有一个 IReadOnlyList<RoadLaneDto> 类型的属性.为了在其他地方兼容,我将其更改为 RoadLaneDto[] .现在,当我反序列化旧数据时,出现此错误:

Newtonsoft.Json.JsonSerializationException : Type specified in JSON 'System.Collections.Generic.List`1[[Asi.Shared.Interfaces.DTOs.Map.RoadLaneDto, Asi.Shared.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not compatible with 'Asi.Shared.Interfaces.DTOs.Map.RoadLaneDto[], Asi.Shared.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Path 'Shapes[0].Lanes.$type', line 78, position 132.

使这些兼容的正确方法是什么?我可以制作 $type 吗?建议而不是要求?我可以编写某种自定义转换器来处理这种情况吗?

最佳答案

一般来说,我不建议序列化集合类型,正是因为这个原因:您希望可以自由更改集合类型(尽管不一定是集合 item 的类型)而不会出现序列化问题.如果您想使用不同于 Json.NET 默认值的特定集合类型实现集合接口(interface)值属性,请说 HashSet<T>对于 ICollection<T> ,您可以在包含类的默认构造函数中分配它,Json.NET 将使用预先分配的集合。要仅序列化对象类型而不序列化集合类型,请设置 TypeNameHandling = TypeNameHandling.Objects .

话虽如此,以下转换器在反序列化等级为 1 的数组时将吞下类型信息:

public class IgnoreArrayTypeConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.IsArray && objectType.GetArrayRank() == 1 && objectType.HasElementType;
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (!CanConvert(objectType))
throw new JsonSerializationException(string.Format("Invalid type \"{0}\"", objectType));
if (reader.TokenType == JsonToken.Null)
return null;
var token = JToken.Load(reader);
var itemType = objectType.GetElementType();
return ToArray(token, itemType, serializer);
}

private static object ToArray(JToken token, Type itemType, JsonSerializer serializer)
{
if (token == null || token.Type == JTokenType.Null)
return null;
else if (token.Type == JTokenType.Array)
{
var listType = typeof(List<>).MakeGenericType(itemType);
var list = (ICollection)token.ToObject(listType, serializer);
var array = Array.CreateInstance(itemType, list.Count);
list.CopyTo(array, 0);
return array;
}
else if (token.Type == JTokenType.Object)
{
var values = token["$values"];
if (values == null)
return null;
return ToArray(values, itemType, serializer);
}
else
{
throw new JsonSerializationException("Unknown token type: " + token.ToString());
}
}

public override bool CanWrite { get { return false; } }

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

然后你可以像这样使用它:

public class RootObject
{
[JsonProperty(TypeNameHandling = TypeNameHandling.None)] // Do not emit array type information
[JsonConverter(typeof(IgnoreArrayTypeConverter))] // Swallow legacy type information
public string[] Lanes { get; set; }
}

或者,您可以在设置中全局使用转换器并让它吞下所有数组的类型信息:

    var settings = new JsonSerializerSettings { Converters = new JsonConverter[] { new IgnoreArrayTypeConverter() }, TypeNameHandling = TypeNameHandling.All };

Json.NET 确实支持多维数组,因此可以扩展对秩 > 1 的数组的支持。

关于c# - 如果不兼容,让 Json.NET 忽略 $type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33159959/

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