web-dev-qa-db-fra.com

Erreur lors de la lecture de JObject à partir de JsonReader. L'élément JsonReader actuel n'est pas un objet: StartArray. Chemin

Je travaille sur une application Windows Phone 8.1 impliquant un emplacement. Je reçois des données Json de mon API. Mon API renvoie des données qui ressemblent à:

[{
    "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"
}]

Je désérialise mes données Json et les mets dans une classe nommée LocationData. Lorsque je lance mon code, cela me donne une erreur:

Erreur lors de la lecture de JObject à partir de JsonReader. L'élément JsonReader actuel n'est pas un objet: StartArray. Chemin

Où vais-je mal? Voici mon code:

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

J'ai aussi essayé d'utiliser un JArray. Mon code est comme ci-dessous:

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

Cela me donne aussi une erreur:

Impossible de désérialiser le tableau JSON actuel (par exemple, [1,2,3]) dans le type 'MMI_SpeechRecog.Model.LocationData' parce que le type nécessite un objet JSON (par exemple, {"name":"value"}) pour désérialiser correctement.

45
iam.Carrot

La première partie de votre question est un doublon de Pourquoi ai-je une exception JsonReaderException avec ce code? , mais la partie la plus pertinente de cette (ma) réponse est la suivante:

[A] JObject n'est pas le type de base élémentaire de tout dans JSON.net, mais JToken l'est. Donc, même si vous pouvez dire,

object i = new int[0];

en C #, vous ne pouvez pas dire,

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

dans JSON.net.

Ce que tu veux c'est JArray.Parse, qui acceptera le tableau que vous passez (noté par l’ouverture [ dans votre réponse API). C'est ce que le "StartArray" dans le message d'erreur vous dit.

En ce qui concerne ce qui s’est passé quand vous avez utilisé JArray, vous utilisez arr au lieu de obj:

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

Échangez cela et je crois que cela devrait fonctionner.

Bien que je serais tenté de désérialiser arr directement comme un IEnumerable<LocationData>, ce qui économiserait du code et des efforts pour boucler le tableau. Si vous n'utilisez pas la version analysée séparément, il est préférable de l'éviter.

70
Matthew Haugen

Dans le cas où vous savez que vous avez tous les éléments en premier sur le tableau, vous pouvez analyser la chaîne dans JArray, puis analyser le premier élément à l'aide de 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());
24
Yohan

J'ai rencontré un problème très similaire avec mon application Xamarin Windows Phone 8.1. La raison pour laquelle JObject.Parse (json) ne fonctionnait pas pour moi était parce que mon Json avait un début "[" et une fin "]". Afin de le faire fonctionner, j'ai dû supprimer ces deux personnages. D'après votre exemple, il semblerait que vous ayez le même problème.

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

J'ai alors pu utiliser le JObject.Parse (jsonResult) et tout a fonctionné.

7
Stacy