升级JsonApiSerializer至1.74版本时自定义转换器失效问题
JsonApiSerializer升级至1.74后自定义转换器失效问题
我在项目中使用JsonApiSerializer,将其从1.3.1版本升级到最新的1.74版本后,自定义转换器无法正确反序列化JSON。转换器的ReadJson方法断点从未命中,反而一直执行CanConvert方法(该方法返回false)。
收到的错误信息:
JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.String' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly. To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'data[0].relationships.matches.data[0].type'.
待反序列化的对象
public class PubgPlayer : PubgShardedEntity { [JsonProperty("Name")] public string Name { get; set; } [JsonProperty] public DateTime CreatedAt { get; set; } [JsonProperty] public string PatchVersion { get; set; } [JsonProperty] public string TitleId { get; set; } [JsonProperty("matches")] [JsonConverter(typeof(RelationshipIdConverter))] public IEnumerable<string> MatchIds { get; set; } }
自定义转换器代码
public class RelationshipIdConverter : JsonConverter { public override bool CanConvert(Type objectType) => false; public override bool CanWrite => false; public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { //if the reader is not reading a relationship object just deserialize as normal. //This allows us to serialize and deserialize multiple times after converting from the Json-API format if (reader.TokenType != JsonToken.StartObject) return serializer.Deserialize(reader, objectType); JToken jt = JToken.Load(reader); var dataToken = jt.SelectToken("data"); if (objectType == typeof(string)) return dataToken["id"].ToString(); return dataToken.Select(x => (string)x["id"]).ToList(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { } }
示例JSON
{ "data":[ { "type":"player", "id":"account.f96f1d482a5d4a21a4135f598f5a5c6a", "attributes":{ "name":"Nomad_o7", "stats":null, "titleId":"pubg", "shardId":"steam", "patchVersion":"" }, "relationships":{ "assets":{ "data":[ ] }, "matches":{ "data":[ { "type":"match", "id":"e14ca749-3c19-49dd-9486-03de90669fa3" }, { "type":"match", "id":"73dbca3e-eeee-44eb-9c43-3f71df0e02ae" }, { "type":"match", "id":"e9f80ed0-1e78-4500-950f-174028fb73cc" } ] } }, "links":{ "self":"https://api.pubg.com/shards/steam/players/account.f96f1d482a5d4a21a4135f598f5a5c6a", "schema":"" } }, { "type":"player", "id":"account.82bad0072f31455d8d9f8d834da2f2f3", "attributes":{ "name":"TGLTN", "stats":null, "titleId":"pubg", "shardId":"steam", "patchVersion":"" }, "relationships":{ "assets":{ "data":[ ] }, "matches":{ "data":[ { "type":"match", "id":"4a6f064e-c292-4e9b-a3a6-bbaed891ce27" }, { "type":"match", "id":"efd9434c-4116-4b56-815d-e30903b37c23" }, { "type":"match", "id":"c1e56bff-db4c-470b-bb44-3c2068e33245" }, { "type":"match", "id":"44d27efc-3cc6-4935-8bbe-702e4da44744" }, { "type":"match", "id":"be3ebed3-9183-47f1-b4b0-40a2229dd5ff" } ] } }, "links":{ "self":"https://api.pubg.com/shards/steam/players/account.82bad0072f31455d8d9f8d834da2f2f3", "schema":"" } } ], "links":{ "self":"https://api.pubg.com/shards/steam/players?filter[playerNames]=Nomad_o7,TGLTN" }, "meta":{ } }
问题原因及解决方法
核心问题
JsonApiSerializer 1.74版本对转换器的处理逻辑有变更:当转换器的CanConvert返回false时,即便通过[JsonConverter]特性直接指定了转换器,框架也会跳过它,转而使用默认序列化逻辑,从而引发错误。
修复步骤
- 修正
CanConvert方法:让它返回true,或者精准匹配需要处理的类型:
public override bool CanConvert(Type objectType) { return objectType == typeof(string) || typeof(IEnumerable<string>).IsAssignableFrom(objectType); }
这样框架能明确识别该转换器的处理范围,确保ReadJson方法被调用。
- 适配新版本内置逻辑:升级后的JsonApiSerializer已内置JSON:API关系处理能力,可直接用内置特性替代自定义转换器:
[JsonProperty("matches")] [Relationship(IdOnly = true)] public IEnumerable<string> MatchIds { get; set; }
若必须保留自定义转换器,需确保其逻辑与新版本序列化流程兼容,比如增加空值判断避免异常。
- 验证特性配置:确认
[JsonConverter]特性正确应用在目标属性上,且未被全局转换器或配置覆盖。
内容的提问来源于stack exchange,提问作者CyberNomad
相关产品推荐
相关产品推荐

