Как сопоставить массив с индексами с объектом с помощью пользовательского JsonConverter

#c# #.net #.net-core #jsonconverter

#c# #.net #.net-core #jsonconverter

Вопрос:

Я видел пару вопросов относительно того, что я пытаюсь сделать, однако, похоже, они используют JSON.Net, который я не хочу использовать в качестве .NET Core / .NET 5, имеет встроенный JsonSerializer.

Я вызываю API для HTTP RPC для RuTorrent, который отвечает словарем <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.
 

Может кто-нибудь, пожалуйста, указать мне правильное направление или указать, что я делаю неправильно?

Спасибо.

Ответ №1:

Оказывается, я неправильно понял, кем на самом деле был читатель. Это содержит большой двоичный объект JSON массива, и я не передавал ссылку на reader.

Правильное решение было таким…

Модели:

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

JsonConverter:

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