Как десериализовать данные json из аукционного API World of Warcraft с помощью Json.NET

Вот пример фрагмента данных json, которые возвращает API:

{
"realm":{"name":"Molten Core","slug":"molten-core"},
"auctions":{"auctions":[
    {"auc":1880591075,"item":109128,"owner":"Leagra","ownerRealm":"Azjol-Nerub","bid":858600,"buyout":900000,"quantity":100,"timeLeft":"VERY_LONG","rand":0,"seed":0,"context":0},
    {"auc":1879726534,"item":43115,"owner":"Nêwt","ownerRealm":"Azjol-Nerub","bid":5120000,"buyout":5120000,"quantity":16,"timeLeft":"VERY_LONG","rand":0,"seed":835268864,"context":0}]}
}

(Хотя с реальными данными очевидно, что есть тысячи аукционов.)

Я хочу десериализовать это, игнорируя данные области и просто помещая аукционы в хороший чистый объект List<WowAuction>, где WowAuction означает:

public class WowAuction
{
      public long auc { get; set; }
      public long item { get; set; }
      public long bid { get; set; }
      public long buyout { get; set; }
}

У меня возникли проблемы с тем, как я это сделаю, json, возвращаемый API, кажется мне довольно запутанным (хотя, по общему признанию, я раньше не работал с json).

Насколько я могу судить, есть коллекция под названием «аукционы», внутри которой есть одно поле, также называемое «аукционы», которое представляет собой таблицу, затем эта таблица содержит строки данных аукциона. Как мне это десериализовать?


person Lazyfaith    schedule 26.01.2015    source источник
comment
Имитируйте структуру типа в вашей модели. Создайте несколько дополнительных классов, и все готово.   -  person Jeroen Vannevel    schedule 26.01.2015


Ответы (4)


Есть много способов сделать это, но самый простой способ — создать объект домена с той же структурой, что и ваш JSON:

public class WoWAuctionResponse {
    public WoWRealmInfo Realm {get; set;}
    public WoWAuctionsBody Auctions {get; set;}
}

public class WoWAuctionsBody {
   public List<WoWAuction> Auctions {get; set;}
}

// ...

JsonConvert.DeserializeObject<WoWAuctionResponse>(json);
person slvnperron    schedule 26.01.2015
comment
Спасибо, теперь кажется просто. Я предполагаю, что моя проблема в основном заключалась в несогласии с их выбором форматирования данных и предположении, что должен быть более чистый способ, о котором я не мог думать. - person Lazyfaith; 26.01.2015

Чтобы расширить ответ @slvnperron.

Во-первых, создайте свои классы. Я рекомендую использовать такой инструмент, как json2csharp.

    public class Realm
    {
        public string name { get; set; }
        public string slug { get; set; }
    }

    public class Auction
    {
        public int auc { get; set; }
        public int item { get; set; }
        public string owner { get; set; }
        public string ownerRealm { get; set; }
        public int bid { get; set; }
        public int buyout { get; set; }
        public int quantity { get; set; }
        public string timeLeft { get; set; }
        public int rand { get; set; }
        public int seed { get; set; }
        public int context { get; set; }
    }

    public class Auctions
    {
        public List<Auction> auctions { get; set; }
    }

    public class RootObject
    {
        public Realm realm { get; set; }
        public Auctions auctions { get; set; }
    }

Во-вторых, проанализируйте ваш json. я рекомендую использовать такой инструмент, как Json.net. Вы можете установить его с помощью nuget.

    public static void Main()
    {
        string json = @"{here your json}";
        RootObject m = JsonConvert.DeserializeObject<RootObject>(json);
        Console.WriteLine(m.realm.name.Trim());
    }

здесь наш вывод будет:

Molten Core

Рабочий пример на dotnetfiddle.

person aloisdg    schedule 26.01.2015

Создайте модель своего домена таким образом и десериализуйте свои данные.

internal class WowAuction
{

    [JsonProperty("realm")]
    public Realm Realm { get; set; }

    [JsonProperty("auctions")]
    public Auctions Auctions { get; set; }
}


internal class Realm
{

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("slug")]
    public string Slug { get; set; }
}

internal class Auctions
{

    [JsonProperty("auctions")]
    public Auction[] Auctions { get; set; }
}

internal class Auction
{

    [JsonProperty("auc")]
    public int Auc { get; set; }

    [JsonProperty("item")]
    public int Item { get; set; }

    [JsonProperty("owner")]
    public string Owner { get; set; }

    [JsonProperty("ownerRealm")]
    public string OwnerRealm { get; set; }

    [JsonProperty("bid")]
    public int Bid { get; set; }

    [JsonProperty("buyout")]
    public int Buyout { get; set; }

    [JsonProperty("quantity")]
    public int Quantity { get; set; }

    [JsonProperty("timeLeft")]
    public string TimeLeft { get; set; }

    [JsonProperty("rand")]
    public int Rand { get; set; }

    [JsonProperty("seed")]
    public int Seed { get; set; }

    [JsonProperty("context")]
    public int Context { get; set; }
}

Позже у вас может быть следующий оператор для десериализации ваших данных

JsonConvert.DeserializeObject<WowAuction>(data); 
person Hari Prasad    schedule 26.01.2015

Все немного изменилось с тех пор, как этот вопрос был изначально задан. API World of Warcraft теперь включает API игровых данных и профилей. Как описано в других ответах здесь, вы можете создавать классы моделей и использовать Json.NET или аналогичную библиотеку для справиться с десериализацией. Существуют также пакеты NuGet, такие как клиент Argent Pony Warcraft или BattleMuffin Blizzard API Client, которые уже определили классы моделей и обрабатывают десериализацию для вас.

Ниже приведен пример с пакетом NuGet ArgentPonyWarcraftClient. Он отображает подмножество информации, доступной для каждого аукциона.

string clientId = "CLIENT-ID-GOES-HERE";
string clientSecret = "CLIENT-SECRET-GOES-HERE";

int connectedRealmId = 1146;

IAuctionHouseApi warcraftClient = new WarcraftClient(
    clientId: clientId,
    clientSecret: clientSecret,
    region: Region.US,
    locale: Locale.en_US);

RequestResult<AuctionsIndex> result = await warcraftClient.GetAuctionsAsync(connectedRealmId, "dynamic-us");

if (result.Success)
{
    AuctionsIndex auctions = result.Value;

    foreach(Auction auction in auctions.Auctions)
    {
        Console.WriteLine($"{auction.Id}: Item ID: {auction.Item.Id} Quantity: {auction.Quantity}");
    }
}
person Dan Jagnow    schedule 25.07.2020