2016-01-09 8 views
15

Pracuję nad aplikacją Windows Phone 8.1 związaną z lokalizacją. Otrzymuję dane Json z mojego API. Moi API zwraca dane, które wygląda następująco:Błąd odczytu JObject z JsonReader. Bieżący obiekt JsonReader nie jest obiektem: StartArray. Ścieżka

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

jestem deserializacji moich danych JSON i wprowadzenie go do klasy o nazwie LocationData. Po uruchomieniu kodu generuję błąd:

Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path

Gdzie się mylę? Oto mój kod:

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

Próbowałem również użyć JArray. Moje kodu jest jak poniżej:

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

To również daje mi błąd:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'MMI_SpeechRecog.Model.LocationData' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

Odpowiedz

33

Pierwsza część Twoje pytanie jest duplikatem Why do I get a JsonReaderException with this code?, ale najbardziej odpowiednia część z tego (moim) odpowiedź jest to:

[A] JObject isn't the elementary base type of everything in JSON.net, but JToken is. So even though you could say,

object i = new int[0]; 

in C#, you can't say,

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

in JSON.net.

Co chcesz jest JArray.Parse, która będzie akceptować tablicę jesteś przechodzącą go (oznaczone przez otwór [ w swojej odpowiedzi API). To właśnie mówi ci "StartArray" w komunikacie o błędzie.

chodzi o to, co się stało, gdy używany JArray, używasz arr zamiast obj:

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

swap i wierzę, to powinno działać.

Chociaż byłbym skłonny do deserializacji arr bezpośrednio jako IEnumerable<LocationData>, co zaoszczędziłoby trochę kodu i wysiłku w zapętleniu się tablicy. Jeśli nie zamierzasz używać oddzielnie przeanalizowanej wersji, najlepiej tego unikać.

+1

Dzięki za odpowiedź. Będę używał przeanalizowanych danych osobno. W tym przypadku odpowiedziałem na moje 4 mecze wyszukiwania. Muszę wyświetlić je pojedynczo, a następnie przeprowadzić tło dla każdego na podstawie preferencji użytkownika. –

+0

Myślę, że powinieneś używać JToken, jeśli chcesz wesprzeć wszystkie przypadki, zobacz ich kod źródłowy tutaj: http://www.jsonschemavalidator.net/ –

3

Wpadłem na bardzo podobny problem z moją aplikacją Xamarin Windows Phone 8.1. Powodem, dla którego JObject.Parse (json) nie zadziałałby dla mnie było to, że mój Json miał początek "[" i zakończenie "]". Aby to zadziałało, musiałem usunąć te dwie postacie. Z Twojego przykładu wygląda na to, że możesz mieć ten sam problem.

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

Byłem wtedy w stanie użyć JObject.Parse (jsonResult) i wszystko działało.

+1

Dzięki za pomoc. Chociaż zostały one po prostu umieszczone przeze mnie w moim pliku tekstowym. Powinienem je usunąć. –

5

W tym przypadku, gdy wiesz, że masz wszystkie przedmioty na pierwszym miejscu na tablicy można analizować ciąg JArray a następnie zanalizować pierwszy element za pomocą 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());