首页 > 解决方案 > 使用 System.Text.Json 转换不一致的 json 值

问题描述

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

System.Text.Json.JsonException :无法将 JSON 值转换为 Models.Error。路径:$.errors | 行号:8 | BytePositionInLine: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 中真的很容易,但不幸的是我不能在这里使用它。

标签: c#json.netsystem.text.json

解决方案


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

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; }
}

推荐阅读