使用 JsonSerializer.DeserializeAsync 反序列化 JSON 没有使用我的 JsonConverter

Ros*_*oss 5 .net c# json deserialization system.text.json

服务器正在返回一个 JSON 字符串值,它是一个 URL 查询字符串:

{
    "parameters": "key1=value1&key2=value2"
}
Run Code Online (Sandbox Code Playgroud)

我设置了一个属性来接收它,并将其转换Dictionary为反序列化过程的一部分:

具有JsonConverter属性的属性:

[JsonConverter(typeof(QueryStringToDictionaryJsonConverter))]
public Dictionary<string, string> Parameters { get; set; }
Run Code Online (Sandbox Code Playgroud)

转换器:

public class QueryStringToDictionaryJsonConverter : JsonConverter<Dictionary<string, string>> {

    public override Dictionary<string, string> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {

        var queryString = reader.GetString();
        if (string.IsNullOrEmpty(queryString)) return null;

        return QueryHelpers.ParseQuery(queryString).ToDictionary(e => e.Key, e => string.Join(",", e.Value.ToArray()));

    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

这应该有效。

但它甚至没有到达我的转换器。

据我所知,JsonSerializer.DeserializeAsync<T>(myJson)看到属性的类型是 a Dictionary,因此它尝试自行解析该值,但失败了(结果异常是“无效转换”,因为它试图GetEnumerable()等)。我的转换器中的断点甚至从未被击中。

我可以通过将属性设置为 anobject然后将其转换为Dictionary稍后使用它的地方来使其工作,但这是一个丑陋的解决方案。

有没有办法强制JsonSerializer.DeserializeAsync<T>(myJson)只使用我的转换器,而不需要它自己尝试智能?

(我在 .NET Core 3 中使用 Microsoft 的 System.Text.Json)

Ros*_*oss 2

好的,所以这可能是System.Text.Json.

这是我目前为其他需要解决方案的人使用的解决方法。

首先,我使用[JsonPropertyName]和设置两个用于反序列化的属性[JsonIgnore]

[JsonPropertyName("parameters"), JsonConverter(typeof(QueryStringToDictionaryJsonConverter))]
public object ParametersObject { get; set; }

[JsonIgnore]
public Dictionary<string, string> Parameters => ParametersObject as Dictionary<string, string>;
Run Code Online (Sandbox Code Playgroud)

然后在 中JsonConverter,我允许object作为类型:

public override bool CanConvert(Type typeToConvert) {
    if (typeToConvert == typeof(object)) return true;
    return base.CanConvert(typeToConvert);
}
Run Code Online (Sandbox Code Playgroud)

我的反序列化类的使用者只需使用该Parameters属性,如果该错误得到修复并且我将类改回我想要的方式,该属性将继续正常工作。