使用 System.Text.Json 转换不一致的 json 值 [重复]

Posted

技术标签:

【中文标题】使用 System.Text.Json 转换不一致的 json 值 [重复]【英文标题】:Converting inconsistent json values using System.Text.Json [duplicate] 【发布时间】:2021-12-17 10:27:05 【问题描述】:

我正在使用的服务返回一个空数组,而不是对象的 null。这会在反序列化过程中导致错误。

System.Text.Json.JsonException:无法转换 JSON 值 到 Models.Error。路径:$.errors |行号:8 |字节位置线: 13.

示例 #1:


  "data": 
    "code": 100,
    "message": "Success",
    "authority": "A00000000000000000000000000112233444",
    "fee_type": "Payer",
    "fee": 10
  ,
  "errors": []

示例 #2:


  "data": [],
  "errors": 
    "code": -9,
    "message": "The input params invalid, validation error."
  

这是它想出的:

internal class InconsistentConverter<T> : JsonConverter<T>

    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    
        if (reader.TokenType == JsonTokenType.StartArray)
        
            _ = reader.Read();
            return default;
        

        return JsonSerializer.Deserialize<T>(ref reader, options);
    

    public override void Write(Utf8JsonWriter writer, T objectToWrite, JsonSerializerOptions options)
    
        throw new NotImplementedException();
    

我也想将转换器用于数据:

public class Result<T>
    where T : class

    [JsonPropertyName("data")]
    [JsonConverter(typeof(InconsistentConverter<T>))] // can't do this
    public T? Data  get; set; 

    [JsonPropertyName("errors")]
    [JsonConverter(typeof(InconsistentConverter<Error>))] // this works
    public Error? Error  get; set; 

我想这在 Json.NET 中会很容易,但不幸的是我不能在这里使用它。

【问题讨论】:

要支持强类型通用转换器,您需要使用一些反射并实现 JsonConverterFactory。 docs.microsoft.com/en-us/dotnet/standard/serialization/… @Charlieface 谢谢,这个服务根本不返回单个值,而是在没有值时返回一个空数组。提供的解决方案可能有效,但我认为在这种情况下没有必要。 抱歉,我认为这不对。它要么返回一个空数组,要么返回一个数组中的对象not。所以这些解决方案应该有效。您可以修改它们以改为为空数组返回 null 请忽略我最后的评论,因为我写的是“单值”而不是“数组”。我的实际意思是,在我的情况下,以下解决方案按预期工作,不需要扩展功能。也许我应该删除这个问题,因为它真的很具体。 【参考方案1】:

一种快速的解决方法是创建转换器的非通用版本:

internal class InconsistentConverter : JsonConverter<object>

    public override bool CanConvert(Type typeToConvert) => true;

    public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    
        if (reader.TokenType == JsonTokenType.StartArray)
        
            _ = reader.Read();
            return default;
        

        var deserialize = JsonSerializer.Deserialize(ref reader, typeToConvert, options);
        return deserialize;
    

    public override void Write(Utf8JsonWriter writer, object objectToWrite, JsonSerializerOptions options)
    
        throw new NotImplementedException();
    

并将其用于通用属性:

public class Result<T>
    where T : class

    [JsonPropertyName("data")]
    [JsonConverter(typeof(InconsistentConverter))]
    public T? Data  get; set; 

    [JsonPropertyName("errors")]
    [JsonConverter(typeof(InconsistentConverter<Error>))] // this works
    public Error? Error  get; set; 

【讨论】:

谢谢,我以前试过这个,但我明白了:'Models.Result`1[Models.Response].Data' 上指定的转换器与'Models.Response' 类型不兼容. @PeymanM。请仔细检查我的解决方案。您是否按照答案覆盖了CanConvert

以上是关于使用 System.Text.Json 转换不一致的 json 值 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

System.Text.Json 自定义Converter实现时间转换

System.Text.Json 自定义Converter实现时间转换

在 .net core 3 中将 newtonsoft 代码转换为 System.Text.Json。相当于 JObject.Parse 和 JsonProperty

使用System.Text.Json(.netcore-3.0)代替Newtonsoft.Json的扩展功能是什么?

在命名空间中找不到 System.Text.Json.JsonReaderException

.net core中关于System.Text.Json的使用