Правильно ли включать данные в качестве имени ключа в JSON? - PullRequest
0 голосов
/ 24 января 2019

Я использую API, который предоставляет полезную нагрузку JSON. Одним из свойств JSON является элемент данных, поэтому я не могу десериализовать полезную нагрузку без добавления дополнительных классов.

Вот JSON:

{
      "company": "ABC Inc.",
      "packages": {
          "$package1": {
          "code": "$package1",
          "name": "Foo",
          "price": 1000
        },
        "$package2": {
          "code": "$package2",
          "name": "Bar",
          "price": 2000
        },
        "$package3": {
          "code": "$package3",
          "name": "Another",
          "price": 3000
        }
    }
}

Я могу сериализовать с помощью Newtonsoft.Json со следующими классами:

public class Rootobject
{
    public string company { get; set; }
    public Packages packages { get; set; }
}

public class Packages
{
    public Package1 package1 { get; set; }
    public Package2 package2 { get; set; }
    public Package3 package3 { get; set; }
}

public class Package1
{
    public string code { get; set; }
    public string name { get; set; }
    public int price { get; set; }
}

public class Package2
{
    public string code { get; set; }
    public string name { get; set; }
    public int price { get; set; }
}

public class Package3
{
    public string code { get; set; }
    public string name { get; set; }
    public int price { get; set; }
} 

Используя этот подход, я могу десериализовать с помощью Newtonsoft.Json, но если позже добавится «package4», то мне потребуется внести изменения в код.

Должен ли я отодвинуть разработчика этого API и настаивать на массиве пакетов, а не на том, как он реализован в настоящее время?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Наличие таких дублированных классов значительно уменьшит возможность повторного использования вашего кода.Это может быть лучше достигнуто с помощью списка пакетов:

public class Rootobject
{
    public string company { get; set; }
    public List<Package> packages { get; set; }
}

и класса вашего пакета:

public class Package
{
    public string code { get; set; }
    public string name { get; set; }
    public int price { get; set; }
} 

Это позволит иметь много Package объектов для одной компании.Единственный недостаток заключается в том, что вам также нужно попросить изменить его на массив, но для рассмотрения передовых методов, которые лучше всего подойдут, поскольку номера пакетов не требуются.В идеале вы должны получить полезную нагрузку JSON в виде:

{
      "company": "ABC Inc.",
      "packages": [
        {
          "name": "Foo",
          "price": 1000
        },
        {
          "name": "Bar",
          "price": 2000
        },
        {
          "name": "Another",
          "price": 3000
        }
    ]
}

И, возможно, также получите идентификатор, если name не уникален.

0 голосов
/ 24 января 2019

Вы можете сделать это, используя Dictionary<>, например:

public partial class Rootobject
{
    public string Company { get; set; }
    public Dictionary<string, Package> Packages { get; set; }
}

public partial class Package
{
    public string Code { get; set; }
    public string Name { get; set; }
    public long Price { get; set; }
}

И десериализовать так:

var result = JsonConvert.DeserializeObject<Rootobject>(json);

И использовать это так:

foreach (var element in result.Packages)
{
    Console.WriteLine($"Package: {element.Key} has name {element.Value.Name}");
}

Что бы вывести:

Package: $package1 has name Foo
Package: $package2 has name Bar
Package: $package3 has name Another
...