Ошибка чтения JObject из JsonReader. Текущий элемент JsonReader не является объектом: StartArray. Дорожка

Я работаю над приложением Windows Phone 8.1 с участием местоположения. Я получаю данные Json из моего API. Мой API возвращает данные, которые выглядят следующим образом:

[{
    "country": "India",
    "city": "Mall Road, Gurgaon",
    "area": "Haryana",
    "PLZ": "122002",
    "street": "",
    "house_no": "",
    "POI": "",
    "type": "17",
    "phone": "",
    "lng": 77.08972334861755,
    "lat": 28.47930118040612,
    "formatted_address": "Mall Road, Gurgaon 122002, Haryana, India"
},
{
    "country": "India",
    "city": "Mall Road, Kanpur",
    "area": "Uttar Pradesh",
    "PLZ": "208004",
    "street": "",
    "house_no": "",
    "POI": "",
    "type": "17",
    "phone": "",
    "lng": 80.35783410072327,
    "lat": 26.46026740300029,
    "formatted_address": "Mall Road, Kanpur 208004, Uttar Pradesh, India"
},
{
    "country": "India",
    "city": "Mall Road Area, Amritsar",
    "area": "Punjab",
    "PLZ": "143001",
    "street": "",
    "house_no": "",
    "POI": "",
    "type": "17",
    "phone": "",
    "lng": 74.87286686897278,
    "lat": 31.64115178002094,
    "formatted_address": "Mall Road Area, Amritsar 143001, Punjab, India"
},
{
    "country": "India",
    "city": "Vasant Kunj (Mall Road Kishan Garh), New Delhi",
    "area": "Delhi",
    "PLZ": "110070",
    "street": "",
    "house_no": "",
    "POI": "",
    "type": "18",
    "phone": "",
    "lng": 77.1434211730957,
    "lat": 28.51363217008815,
    "formatted_address": "Vasant Kunj (Mall Road Kishan Garh), New Delhi 110070, Delhi, India"
}]

Я десериализую свои данные Json и помещаю его в класс с именем LocationData. Когда я запускаю свой код, это дает мне ошибку:

Ошибка чтения JObject из JsonReader. Текущий элемент JsonReader не является объектом: StartArray. Путь

Где я ошибаюсь? Вот мой код:

private async void GetAPIData()
    {
        string _serviceUrl = "https://api.myweblinkapiprovider/v2&q=" + UserRequestedLocation;
        HttpClient client = new HttpClient();

        HttpResponseMessage responce = await client.GetAsync(new Uri(_serviceUrl));

        if (responce.Content != null)
        {
            var respArray = JObject.Parse(await responce.Content.ReadAsStringAsync());
            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.NullValueHandling = NullValueHandling.Ignore;
            settings.MissingMemberHandling = MissingMemberHandling.Ignore;
            var rcvdData = JsonConvert.DeserializeObject<LocationData>(respArray.ToString(), settings);
            UpdateMapData(rcvdData);
            UpdateTextData(rcvdData);
        }
    }

Я также пытался использовать JArray. Мой код выглядит следующим образом:

 private async void GetAPIData()
    {
        string _serviceUrl = "https://api.myweblinkprovider.com/v3?fun=geocode&lic_key=MyKey" + UserRequestedLocation;
        HttpClient client = new HttpClient();

        HttpResponseMessage responce = await client.GetAsync(new Uri(_serviceUrl));

        JArray arr = JArray.Parse(await responce.Content.ReadAsStringAsync());

        foreach (JObject obj in arr.Children<JObject>())
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.NullValueHandling = NullValueHandling.Ignore;
            settings.MissingMemberHandling = MissingMemberHandling.Ignore;
            var rcvdData = JsonConvert.DeserializeObject<LocationData>(arr.ToString(), settings);
            UpdateMapData(rcvdData);
            UpdateTextData(rcvdData);
        }
    }

Это также дает мне ошибку:

Невозможно десериализовать текущий массив JSON (например, [1,2,3]) в type 'MMI_SpeechRecog.Model.LocationData', потому что для правильного десериализации этот тип требует объекта JSON (например, {"name":"value"}).

Ответы

Ответ 1

Первая часть вашего вопроса - это дубликат Почему я получаю исключение JsonReaderException с этим кодом?, но наиболее важная часть этого (моего) ответа это:

[A] JObject не является элементарным базовым типом всего в JSON.net, но JToken is. Поэтому, хотя вы могли бы сказать,

object i = new int[0];

в С#, вы не можете сказать,

JObject i = JObject.Parse("[0, 0, 0]");

в JSON.net.

Вы хотите JArray.Parse, который примет массив, который вы передаете ему (обозначается открытием [ в ответе API). Это то, что сообщает "StartArray" в сообщении об ошибке.

Что касается того, что произошло, когда вы использовали JArray, вы используете arr вместо obj:

var rcvdData = JsonConvert.DeserializeObject<LocationData>(arr /* <-- Here */.ToString(), settings);

Поменяйте это, и я считаю, что он должен работать.

Хотя у меня возникнет соблазн десериализовать arr непосредственно как IEnumerable<LocationData>, который сохранит некоторый код и усилие цикла по массиву. Если вы не собираетесь использовать разборную версию отдельно, лучше избегать ее.

Ответ 2

В этом случае, когда вы знаете, что у вас есть все элементы в первом месте массива, вы можете проанализировать строку в JArray и затем проанализировать первый элемент с помощью JObject.Parse

var  jsonArrayString = @"
[
  {
    ""country"": ""India"",
    ""city"": ""Mall Road, Gurgaon"",
  },
  {
    ""country"": ""India"",
    ""city"": ""Mall Road, Kanpur"",
  }
]";
JArray jsonArray = JArray.Parse(jsonArrayString);
dynamic data = JObject.Parse(jsonArray[0].ToString());

Ответ 3

У меня возникла очень похожая проблема с моим Xamarin Windows Phone 8.1. Причина JObject.Parse(json) не сработала для меня, потому что у моего Json было начало "[" и окончание "]". Чтобы заставить его работать, мне пришлось удалить эти два персонажа. Из вашего примера, похоже, у вас может быть такая же проблема.

jsonResult = jsonResult.TrimStart(new char[] { '[' }).TrimEnd(new char[] { ']' });

Тогда я смог использовать JObject.Parse(jsonResult), и все сработало.