Как я могу десериализовать сложный и вложенный JSON? - PullRequest
2 голосов
/ 27 марта 2019

В моем проекте на c # я хотел бы получить доступ к конкретной информации (POI имя и расстояние ) внутри комплекса и вложенного JSON .

Этот JSON является результатом вызова API Azure Maps.

Я пытался десериализовать его в объект. Но этот JSON слишком сложен, и я не могу этого сделать.

Как лучше всего извлечь нужную мне информацию?

{
  "summary": {
    "query": "university",
    "queryType": "NON_NEAR",
    "queryTime": 103,
    "numResults": 1,
    "offset": 0,
    "totalResults": 216684,
    "fuzzyLevel": 1,
    "geoBias": {
      "lat": 48.008446,
      "lon": 7.821583
    }
  },
  "results": [
    {
      "type": "POI",
      "id": "DE/POI/p0/1505647",
      "score": 2.574,
      "dist": 774.6544330765787,
      "info": "search:ta:276009006412786-DE",
      "poi": {
        "name": "Universität Freiburg Medizinische Fakultät",
        "phone": "+(49)-(761)-27072350",
        "url": "www.med.uni-freiburg.de",
        "categories": [
          "college/university"
        ],
        "classifications": [
          {
            "code": "COLLEGE_UNIVERSITY",
            "names": [
              {
                "nameLocale": "en-US",
                "name": "college/university"
              }
            ]
          }
        ]
      },
      "address": {
        "streetName": "Elsässer Straße",
        "municipalitySubdivision": "Mooswald",
        "municipality": "Freiburg im Breisgau",
        "countrySecondarySubdivision": "Freiburg im Breisgau",
        "countrySubdivision": "Baden-Württemberg",
        "postalCode": "79110",
        "countryCode": "DE",
        "country": "Germany",
        "countryCodeISO3": "DEU",
        "freeformAddress": "Elsässer Straße, 79110 Freiburg Im Breisgau"
      },
      "position": {
        "lat": 48.00894,
        "lon": 7.83197
      },
      "viewport": {
        "topLeftPoint": {
          "lat": 48.00984,
          "lon": 7.83063
        },
        "btmRightPoint": {
          "lat": 48.00804,
          "lon": 7.83331
        }
      },
      "entryPoints": [
        {
          "type": "main",
          "position": {
            "lat": 48.00931,
            "lon": 7.83259
          }
        }
      ]
    }
  ]
}

Ответы [ 3 ]

1 голос
/ 27 марта 2019

У вас есть как минимум 2 возможных решения:

Либо вы создаете классы, которые отражают содержимое ожидаемого json

public class MyJSON
{
  public Summary summary { get; set; }

  public List<Result> results { get; set; }
  ...
}

public class Summary
{
   public string query { get; set; }
   ...
}

Тогда вы можете десериализовать, используя Newtonsoft.Json

JsonConvert.DeserializeObject<MyJSON>(jsonstring);

Или вы можете напрямую десериализовать динамический объект и получить доступ к свойствам напрямую по имени.

  dynamic data = JsonConvert.DeserializeObject<dynamic>(jsonstring);      
  string query = data[0].summary.query;

Решение 1 требует, чтобы вы сначала создали классы, но быстрее и безопаснее для доступа (менее подвержены неправильному именованию или изменениям структуры данных)

Решение 2 гораздо более изменчиво и гибко, вы просто получаете доступ к тому, что вам нужно. Но вы можете получить исключения, если попытаетесь получить доступ к свойствам, которые не существуют в объекте json.

1 голос
/ 27 марта 2019

я преобразовал ваш JSON с помощью json2csharp тогда вы можете использовать Newtonsoft для десериализации их

RootObject root = JsonConvert.DeserializeObject (JSONstring)

   public class GeoBias
    {
        public double lat { get; set; }
        public double lon { get; set; }
    }

    public class Summary
    {
        public string query { get; set; }
        public string queryType { get; set; }
        public int queryTime { get; set; }
        public int numResults { get; set; }
        public int offset { get; set; }
        public int totalResults { get; set; }
        public int fuzzyLevel { get; set; }
        public GeoBias geoBias { get; set; }
    }

    public class Name
    {
        public string nameLocale { get; set; }
        public string name { get; set; }
    }

    public class Classification
    {
        public string code { get; set; }
        public List<Name> names { get; set; }
    }

    public class Poi
    {
        public string name { get; set; }
        public string phone { get; set; }
        public string url { get; set; }
        public List<string> categories { get; set; }
        public List<Classification> classifications { get; set; }
    }

    public class Address
    {
        public string streetName { get; set; }
        public string municipalitySubdivision { get; set; }
        public string municipality { get; set; }
        public string countrySecondarySubdivision { get; set; }
        public string countrySubdivision { get; set; }
        public string postalCode { get; set; }
        public string countryCode { get; set; }
        public string country { get; set; }
        public string countryCodeISO3 { get; set; }
        public string freeformAddress { get; set; }
    }

    public class Position
    {
        public double lat { get; set; }
        public double lon { get; set; }
    }

    public class TopLeftPoint
    {
        public double lat { get; set; }
        public double lon { get; set; }
    }

    public class BtmRightPoint
    {
        public double lat { get; set; }
        public double lon { get; set; }
    }

    public class Viewport
    {
        public TopLeftPoint topLeftPoint { get; set; }
        public BtmRightPoint btmRightPoint { get; set; }
    }

    public class Position2
    {
        public double lat { get; set; }
        public double lon { get; set; }
    }

    public class EntryPoint
    {
        public string type { get; set; }
        public Position2 position { get; set; }
    }

    public class Result
    {
        public string type { get; set; }
        public string id { get; set; }
        public double score { get; set; }
        public double dist { get; set; }
        public string info { get; set; }
        public Poi poi { get; set; }
        public Address address { get; set; }
        public Position position { get; set; }
        public Viewport viewport { get; set; }
        public List<EntryPoint> entryPoints { get; set; }
    }

    public class RootObject
    {
        public Summary summary { get; set; }
        public List<Result> results { get; set; }
    }
1 голос
/ 27 марта 2019

Шаг 1: Проанализируйте ваш JSON на веб-сайте анализатора JSON, например https://jsonparser.org Это поможет вам понять содержание и то, как оно будет переведено как объект. Например, ваша строка JSON дает такой результат:

enter image description here

Шаг 2: Откройте инструмент запросов этого веб-сайта, это поможет вам найти путь к нужной информации. Например, для вашей строки JSON для доступа к имени POI:

enter image description here

Шаг 3: В вашем проекте Visual Studio установите пакет NuGet: Newtonsoft.Json и Microsoft.CSharp в вашей общей библиотеке. Если вы обрабатываете JSON в отдельной библиотеке, пожалуйста, также установите пакет Newtonsoft.Json NuGet в основной проект.

Шаг 4: Если JSONstring является вашей строкой JSON:

using Newtonsoft.Json;

dynamic NewObject = JsonConvert.DeserializeObject<dynamic>(JSONstring);


string Name = NewObject.results[0].poi.name;

string Distance = NewObject.results[0].dist;
...