首页 > 解决方案 > 如何将具有索引的数组映射到具有自定义 JsonConverter 的对象

问题描述

我已经看到了一些关于我正在尝试做什么的问题,但是他们似乎正在使用 JSON.Net,这是我不想使用的,因为 .NET Core / .NET 5 内置了 JsonSerializer。

我正在为 RuTorrent 调用 HTTP RPC 的 API,它以字典 <string, string[]> 进行响应。我想要做的是将此字符串数组的索引映射到一个对象。

来自 PostMan 的响应示例;

{
    "t": {
        "4CBF8EFCF0797955A7CA79A3CE85D81C8F8B851C": [
            "1",
            "0",
            "1",
            "1",
            "Torrent One",
            "4113182720",
            "1962",
            "1962",
            "4113182720",
            "0",
            "0",
            "0",
            "0",
            "2097152",
            "",
            "0",
            "0",
            "0",
            "0",
            "0",
            "2",
            "1606214313",
            "0",
            "0",
            "1962",
            "/downloads/",
            "0",
            "1",
            "1",
            "",
            "",
            "1282428129280",
            "1",
            "1"
        ],
        "C439916345971D344290D4D5E1F813E3BA37873C": [
            "1",
            "0",
            "1",
            "1",
            "Torrent Two",
            "13072611982",
            "24935",
            "24935",
            "13072611982",
            "7661161341",
            "586",
            "0",
            "0",
            "524288",
            "",
            "0",
            "0",
            "0",
            "0",
            "0",
            "2",
            "1606214313",
            "0",
            "0",
            "24935",
            "/downloads",
            "1353858437",
            "1",
            "1",
            "",
            "",
            "1282428129280",
            "1",
            "1"
        ]
    }
}

到目前为止,这是我的模型;

public class Result
{
    [JsonPropertyName("t")]
    public IDictionary<string, Torrent> Torrents { get; set; }
    
    public int cid { get; set; }
}

[JsonConverter(typeof(TorrentConverter<String>))]
public class Torrent
{
    public string TorrentName { get; set; }
}

到目前为止,这就是我的转换器中的所有内容(请注意,.Dump() 是您可以在程序 LinqPad 中使用的一种方法,用于将对象的内容转储到窗口):

public class TorrentConverter<String> : JsonConverter<Torrent>
{   
    public override Torrent Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        reader.GetString().Dump();
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, Torrent value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

我不确定如何使用 Utf8JsonReader 参数。到目前为止,我已经尝试过反序列化和 .GetString() 但是它不断抛出 JsonException 并带有以下内容:

The JSON value could not be converted to System.Collections.Generic.Dictionary`2[System.String,UserQuery+Torrent]. Path: $.t.4CBF8EFCF0797955A7CA79A3CE85D81C8F8B851C | LineNumber: 0 | BytePositionInLine: 50.

有人可以指出我正确的方向或指出我做错了什么吗?

谢谢。

标签: c#.net.net-corejsonconverter

解决方案


原来我误解了读者的真实身份。这包含数组的 JSON blob,我没有传递阅读器的 ref。

正确的解决方案是这样的......

楷模:

public class Result
{
    [JsonPropertyName("t")]
    public IDictionary<string, Torrent> Torrents { get; set; }
    
    public int cid { get; set; }
}

[JsonConverter(typeof(TorrentConverter))]
public class Torrent
{
    public Torrent(IEnumerable<string> data)
    {
        TorrentName = data.ElementAt(4);
    }
    
    public string TorrentName { get; set; }
}

json转换器:

public class TorrentConverter : JsonConverter<Torrent>
{
    public override Torrent Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var blob = JsonSerializer.Deserialize<string[]>(ref reader);

        return new Torrent(blob);
    }

    public override void Write(Utf8JsonWriter writer, Torrent value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

推荐阅读