Hallo, ich versuche einen bestimmten Wert aus einer Wetterdienst API in Form eines Json Files auszulesen.
Ich kann die gesamte Json File in der Variable jsonInhalt anzeigen lassen aber sobald ich aus der Klasse einen bestimmten Wert rauspicken möchte, bleibt die Variable leer. Der Compiler (visual studio) spuckt auch keine Fehlermeldung raus, die abgerufene Variable bleibt einfach leer.
Hab da irgendeinen Matrixfehler im Hirn und kommt nicht drauf bzw. ich hab das Konzept dahinter wohl noch nicht verstanden 🙁
var client = new HttpClient();
try
{
var request = new HttpRequestMessage(HttpMethod.Get, "http://api.weatherapi.com/v1/current.json?key=************"); //Key anonymisiert für den Post, die Seite ist aber abrufbar.
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var jsonInhalt = await response.Content.ReadAsStringAsync();
Console.WriteLine(jsonInhalt); // Dieser Inhalt wird komplett angezeigt in der Console
Location myHome = JsonConvert.DeserializeObject<Location>(jsonInhalt);
Console.WriteLine(myHome.localtime); // Dieser Inhalt wird NICHT angezeigt in der Console. Keine Fehlermeldung
Console.ReadLine();
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
client.Dispose();
}
public class Location
{
public string localtime { get; set; }
}
Wo ist da mein Denkfehler?
Hast du schonmal den Debugger verwendet und geschaut was du zurückbekommst?
Ich tippe mal darauf, dass der String null ist, weil das Feld nicht richtig deserialisiert wird.
Dadurch wird dann auch nichts angezeigt.
Kannst du aber mit dem Debugger prüfen.
Nachtrag:
Laut Doku rufst du die Realtime Api auf.
Die liefert dir auch kein Location Objekt, sondern ein Current Objekt.
Doku:
[
Weather and Geolocation API - Free Weather and Geolocation API JSON and XML - WeatherAPI.com](https://www.weatherapi.com/docs/?PageSpeed=noscript#apis-realtime)
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
Mit deinem aktuellen Vorgehen müsste "localtime" ein Key-Value Paar des Root-Objekts sein. Es ist liegt aber unterhalb von "location":
{
"location": {
// ...
"localtime": "2022-06-26 18:48"
},
"current": {
// ...
}
}
Du musst das so auch in deinen C# Klassen abbilden:
public class Rootobject
{
public Location location { get; set; }
}
public class Location
{
public string localtime { get; set; }
}
Das kann Visual Studio automatisch für dich machen, wenn du den folgenden Menüpunkt aufrufst, während dein JSON in der Zwischenablage liegt: Edit - Paste Special - Paste JSON as Classes
PS: Es ist hilfreich für die Leute im Forum, wenn man bei solchen Fragen das zugehörige JSON zur Verfügung stellt.
Edit:
@T-Virus: Die Doku der Api ist nicht wirklich schön. Ich habe zumindest auf die schnelle kein komplettes Beispiel gefunden und deswegen schnell einen Wegwerf-Account erstellt. Aber nachträglich habe ich jetzt in der Doku unter "Location" gelesen:
Location Object
Location object is returned with each API response. [...]
Erstmal super vielen Dank für eure schnellen Antworten.
Hast du schonmal den Debugger verwendet und geschaut was du zurückbekommst?
Ich tippe mal darauf, dass der String null ist, weil das Feld nicht richtig deserialisiert wird.
Dadurch wird dann auch nichts angezeigt.
Kannst du aber mit dem Debugger prüfen.Nachtrag:
Laut Doku rufst du die Realtime Api auf.
Die liefert dir auch kein Location Objekt, sondern ein Current Objekt.Doku:
>T-Virus
Hier ist die volle Adresse (inkl. Key) übrigens die ich nutze
https://api.weatherapi.com/v1/current.json?key=592738e65d4247ccbf3192905222606&q=London&aqi=no
ist quasi die standardseite als beispiel. Du hast im Übrigen recht, dass bei mir der Debugger mich auf null values hinweist
CS8600 Converting null literal or possible null value to non-nullable type.
CS8602 Dereference of a possibly null reference.
CS8618 Non-nullable property 'localtime' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
Aber ich weiß nicht ob da das Problem steckt.
Anscheinend komm ich mit den Objekt und Klassenbezeichnungen durcheinander oder ich hab explizit mit der weatherapi Json ein Problem, denn andere APIS funktionieren und geben mir Werte raus
Das kann Visual Studio automatisch für dich machen, wenn du den folgenden Menüpunkt aufrufst, während dein JSON in der Zwischenablage liegt: Edit - Paste Special - Paste JSON as Classes
Supertip. Danke dafür!
Ich hab das genutzt und entsprechend die Klassen erstellen lassen.
Siehe auch den weatherapi link oben wo man die Json File direkt abrufen kann um die es hier geht.
Dennoch wird bei strings überhaupt kein Wert zurückgegeben und bei Zahlen (float, int, double usw) eine 0
Wie bereits geschrieben, andere APIS funktionieren und geben mir korrekte Werte wieder daher glaub ich inzwischen, dass das an der Seite selbst liegt
Du deserialisierst in ein Objekt, das genau eine Property hat: localtime
Hat das JSON die Property "localtime"? Ich sehe da nur "location:localtime", großer Unterschied 😉
Also ja, dannoe hat Recht, Du brauchst ein Root-Objekt, was dann die location-Property enthält.
Dann musst Du auch kein tolles Visual Studio Feature nutzen, Du hättest einfach seinen Code kopieren können.
PS:
Ich weiß nicht, woher genau man den Key bekommt, aber es ist vermutlich immer eine schlechte Idee, sowas öffentlich zu machen 😉
Du deserialisierst in ein Objekt, das genau eine Property hat: localtime
Hat das JSON die Property "localtime"? Ich sehe da nur "location:localtime", großer Unterschied 😉Also ja, dannoe hat Recht, Du brauchst ein Root-Objekt, was dann die location-Property enthält.
Dann musst Du auch kein tolles Visual Studio Feature nutzen, Du hättest einfach seinen Code kopieren können.PS:
Ich weiß nicht, woher genau man den Key bekommt, aber es ist vermutlich immer eine schlechte Idee, sowas öffentlich zu machen 😉
Hi, hinter der Api und dem Key steckt ein wegwerfaccount mit begrenzter Abrufmöglichkeit insofern egal ^^
Zu dem anderen Punkt: Ich hab da inzwischen gefühlt wie ein menschlicher Bruforce alle möglichen Kombinationen an Klassennamen und Objekten ausprobiert mit dem Ergebnis dass mir da einfach nie ein Wert zurückgegeben wird 😁 Andere Onlineapis funktionieren mit dem Code, das ist das was mich irgendwie stutzig macht. Ich weiß nicht ob es nun an mir, meinem Code oder an der Seite selbst liegt
Ok. Liegt also doch nicht an der Seite sondern der Matrixfehler vor dem Bildschirm wie zu 99%. Bin auf die Lösung gekommen dank eurem Wink mit dem Zaunpfahl mit dem Rootobject. Vielen Dank dafür.
Ich hab zwar eine Rootobject Klasse mit Location und Current allerdings diese nicht zusätzlich deserialisiert
Rootobject Root = JsonConvert.DeserializeObject<Rootobject>(jsonInhalt);
Jetzt klappts auch mit dem Abrufen der Daten
Console.WriteLine(Root.location.name);
Console.WriteLine(Root.current.temp_c);
Warum es auf den anderen Seiten funktionierte lag schlicht und ergreifend daran, dass da keine Rootobject Klasse in der Hierarchie oben nötig waren