2016-07-10 5 views
0

Kürzlich habe ich beschlossen, eine Yahoo Weather PCL-Bibliothek zum Parsen dieser APIs zu schreiben (siehe hier für das gesamte Projekt: https://github.com/huming2207/YahooWeather.NET).Versuchen, JSON zu analysieren, aber "Kann Listentyp nicht erstellen und auffüllen"?

Für die Codierung Umgebung, ich bin Xamarin 6.0.1 mit Mono 4.4.1 auf Mac OSX 10.11.5 und Visual Studio Update 3 auf Windows 10 10586.

Ich habe die meisten der Verwendung getan funktioniert und es funktioniert, bis auf eine Sache.

Das API Abfrageer Yahoo Wetter sollte wie folgt sein:

"item": { 
"title": "Conditions for Nome, AK, US at 02:00 PM AKDT", 
"lat": "64.499474", 
"long": "-165.405792", 
"link": "http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2460286/", 
"pubDate": "Sat, 09 Jul 2016 02:00 PM AKDT", 
"condition": { 
    "code": "26", 
    "date": "Sat, 09 Jul 2016 02:00 PM AKDT", 
    "temp": "55", 
    "text": "Cloudy" 
}, 
"forecast": [ 
    { 
    "code": "28", 
    "date": "09 Jul 2016", 
    "day": "Sat", 
    "high": "55", 
    "low": "50", 
    "text": "Mostly Cloudy" 
    }, 
    { 
    "code": "39", 
    "date": "10 Jul 2016", 
    "day": "Sun", 
    "high": "56", 
    "low": "47", 
    "text": "Scattered Showers" 
    }, 
    { 
    "code": "30", 
    "date": "11 Jul 2016", 
    "day": "Mon", 
    "high": "53", 
    "low": "48", 
    "text": "Partly Cloudy" 
    }, 
    { 
    "code": "32", 
    "date": "12 Jul 2016", 
    "day": "Tue", 
    "high": "59", 
    "low": "47", 
    "text": "Sunny" 
    }, 
    { 
    "code": "30", 
    "date": "13 Jul 2016", 
    "day": "Wed", 
    "high": "58", 
    "low": "50", 
    "text": "Partly Cloudy" 
    }, 
    { 
    "code": "28", 
    "date": "14 Jul 2016", 
    "day": "Thu", 
    "high": "53", 
    "low": "51", 
    "text": "Mostly Cloudy" 
    }, 
    { 
    "code": "30", 
    "date": "15 Jul 2016", 
    "day": "Fri", 
    "high": "56", 
    "low": "51", 
    "text": "Partly Cloudy" 
    }, 
    { 
    "code": "26", 
    "date": "16 Jul 2016", 
    "day": "Sat", 
    "high": "53", 
    "low": "52", 
    "text": "Cloudy" 
    }, 
    { 
    "code": "30", 
    "date": "17 Jul 2016", 
    "day": "Sun", 
    "high": "62", 
    "low": "52", 
    "text": "Partly Cloudy" 
    }, 
    { 
    "code": "30", 
    "date": "18 Jul 2016", 
    "day": "Mon", 
    "high": "56", 
    "low": "47", 
    "text": "Partly Cloudy" 
    } 
], 
"description": "<![CDATA[<img src=\"http://l.yimg.com/a/i/us/we/52/26.gif\"/>\n<BR />\n<b>Current Conditions:</b>\n<BR />Cloudy\n<BR />\n<BR />\n<b>Forecast:</b>\n<BR /> Sat - Mostly Cloudy. High: 55Low: 50\n<BR /> Sun - Scattered Showers. High: 56Low: 47\n<BR /> Mon - Partly Cloudy. High: 53Low: 48\n<BR /> Tue - Sunny. High: 59Low: 47\n<BR /> Wed - Partly Cloudy. High: 58Low: 50\n<BR />\n<BR />\n<a href=\"http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2460286/\">Full Forecast at Yahoo! Weather</a>\n<BR />\n<BR />\n(provided by <a href=\"http://www.weather.com\" >The Weather Channel</a>)\n<BR />\n]]>", 
"guid": { 
    "isPermaLink": "false" 
} 
} 

Also schrieb ich eine „Prognose“ und „Item“ JsonObject Klasse für Json.NET Bibliothek zu erklären, den Json Inhalt zu analysieren, die wie folgt aussieht:

hier ist die "Item" Klasse:

namespace YahooWeatherParser 
{ 
    [JsonObject()] 
    public class Item 
    { 
     [JsonProperty(PropertyName = "title")] 
     public string Title { get; set; } 

     [JsonProperty(PropertyName = "lat")] 
     public double Latitude { get; set; } 

     [JsonProperty(PropertyName = "lon")] 
     public double Longitude { get; set; } 

     [JsonProperty(PropertyName = "link")] 
     public string Link { get; set; } 

     [JsonProperty(PropertyName = "pubDate")] 
     public string PublishDate { get; set; } 

     [JsonProperty(PropertyName = "condition")] 
     public Condition Condition { get; set; } 

     [JsonProperty(PropertyName = "forecast")] 
     public Forecast Forecast { get; set; } 

     [JsonProperty(PropertyName = "description")] 
     public string Description { get; set; } 

     [JsonProperty(PropertyName = "guid")] 
     public Guid Guid { get; set; } 
    } 
} 

... und hier ist die "Prognose" Klasse:

using System; 
using Newtonsoft.Json; 

namespace YahooWeatherParser 
{ 
    [JsonArray] 
    public class Forecast 
    { 
     [JsonProperty(PropertyName = "code")] 
     public int Code { get; set; } 

     [JsonProperty(PropertyName = "date")] 
     public string Date { get; set; } 

     [JsonProperty(PropertyName = "day")] 
     public string Day { get; set;} 

     [JsonProperty(PropertyName = "high")] 
     public int High { get; set; } 

     [JsonProperty(PropertyName = "low")] 
     public int Low { get; set; } 

     [JsonProperty(PropertyName = "text")] 
     public string Text { get; set; } 

    } 
} 

Dann habe ich meinen Code lief, habe ich eine Ausnahme wie diese bekommen:

System.AggregateException: Ein oder mehrere Fehler aufgetreten sind. ---> Newtonsoft.Json.JsonSerializationException: Der Listentyp YahooWeatherParser.Forecast kann nicht erstellt und gefüllt werden. Pfad 'query.results.channel.item.forecast', Zeile 1, Position 1282.

So gegoogelt ich für Lösungen rund um. Ich habe versucht, wenn ich diese Inhalte unter (in "Item" Klasse) ersetzen:

[JsonProperty(PropertyName = "forecast")] 
public Forecast Forecast { get; set; } 

zu:

[JsonProperty(PropertyName = "forecast")] 
public List<Forecast> Forecast { get; set; } 

Er kehrte mir noch eine andere Ausnahme:

System.AggregateException : Ein oder mehrere Fehler sind aufgetreten. ---> Newtonsoft.Json.JsonSerializationException: Kann nicht deserialisiert die aktuellen JSON Objekt (zB { "name": "value"}) in Art 'YahooWeatherParser.Forecast', da der Typ eines Array JSON erfordert (zB [1 , 2,3]), um korrekt zu deserialisieren. Um diesen Fehler entweder zu beheben, ändern Sie den JSON in ein JSON-Array (zB [1,2,3]) oder ändern Sie den deserialisierten Typ , so dass es ein normaler .NET-Typ ist (zB kein primitiver Typ wie ganze Zahl, kein a Sammlungsart wie ein Array oder List), die von einem JSON-Objekt deserialisiert werden kann. JsonObjectAttribute kann auch zum Typ hinzugefügt werden, um es auf deserialize von einem JSON-Objekt zu erzwingen. Pfad 'query.results.channel.item.forecast [0] .code', Zeile 1, Position 1290.

Also ... was soll ich als nächstes tun mit diesem Problem umgehen? Vielen Dank für Ihre Hilfe!

Grüße, Jackson.

+0

Haben Sie versucht, "public Prognose [] Vorhersage {get; set;}" ? –

+0

Ja, ich habe das gleiche Ergebnis wie Liste

+0

Ich benutze DataContractJsonSerializer und funktioniert wie ein Charme, ohne jedes Problem. Verwenden von Forecast [] –

Antwort

1

Ich versuche es ein sauberes Projekt und tatsächlichen newtonsoft json von nuget verwenden, ist Ihr Problem in dieser Linie ist:

using System; 
using Newtonsoft.Json; 

namespace YahooWeatherParser 
{ 
    [JsonObject]    // <= not [JsonArray] !!! 
    public class Forecast 
    { 
     [JsonProperty(PropertyName = "code")] 
     public int Code { get; set; } 

     [JsonProperty(PropertyName = "date")] 
     public string Date { get; set; } 

     [JsonProperty(PropertyName = "day")] 
     public string Day { get; set;} 

     [JsonProperty(PropertyName = "high")] 
     public int High { get; set; } 

     [JsonProperty(PropertyName = "low")] 
     public int Low { get; set; } 

     [JsonProperty(PropertyName = "text")] 
     public string Text { get; set; } 

    } 
} 
0

Mit dem zweiten Fehler klingt es, als ob Sie ein JObject irgendwo im Code erstellen, aber nicht in ein JArray umwandeln, was notwendig ist, weil .NET den Newtonsoft JSON-Typ nicht versteht. Sie können entweder ein JArray abrufen und dieses verwenden, das JObject extrahieren und es dann konvertieren oder die eigene Serialisierungsklasse des .NET-Frameworks verwenden.

foreach(JObject forecast in yourJObjectQueryResult["forecast"]) 
{ 
    string theForecast = forecast.ToString(Formatting.None); 
} 

for (int i=0; i < (JArray)yourJObjectQueryResult["forecast"].Count; i++) 
{ 

} 
+0

Okay danke für deine Antwort. Ich bin ein bisschen verwirrend, dass ich die "Prognose" vielleicht als JArray deklariert habe. Meinst du, ich muss einen JsonConverter hinzufügen, es zuerst konvertieren, dann etwas anderes tun? –

+0

@JacksonMingHu Wo auch immer Sie diesen Fehler in Ihrem Code bekommen, Haltepunkt und überprüfen Sie den Typ für das Objekt, das Ihre JSON hat. Wo auch immer Sie das JObject bei erstellen, können Sie einfach darüber iterieren und die Werte einer Instanz Ihrer Klasse zuweisen. Es ist nicht notwendig, es in ein JArray zu konvertieren, ich habe die zweite Schleife nur als Beispiel eingefügt. –