C
C#β€’13mo ago
GIGA BRAIN

❔ Null warning from accessing weather results from an API call

I'm creating a weather app that allows you to type in the name of a city and then get it's information from which you can use a key to get the weather for it. I've gotten the first part down, but I'm having trouble with the second part in that I try to get the JSON results from a different api link where I need the city key. I keep getting a null warning from my code when I try to get and deserialize the json, but I don't see anything in the JSON itself that has a null value. any suggestions? pastebin of code: https://paste.mod.gg/miyqeovcslff/0 pic of json:
BlazeBin - miyqeovcslff
A tool for sharing your source code with the world!
101 Replies
phaseshift
phaseshiftβ€’13mo ago
depends how you're deserialzing it
GIGA BRAIN
GIGA BRAINβ€’13mo ago
i'm trying to serialize it into an object
phaseshift
phaseshiftβ€’13mo ago
show code...
GIGA BRAIN
GIGA BRAINβ€’13mo ago
in the blazebin or i can paste it here 1 sec
phaseshift
phaseshiftβ€’13mo ago
nah link is good
GIGA BRAIN
GIGA BRAINβ€’13mo ago
ok
phaseshift
phaseshiftβ€’13mo ago
so what is null? weatherResult?
GIGA BRAIN
GIGA BRAINβ€’13mo ago
yeah, let me run the code again real quick and sc it
daysleeper
daysleeperβ€’13mo ago
null warnings usually just say that if you put null into the field it will throw exception so you can put a null reference checker (either ?? or if statement) and it should do assuming that codewise nothing is crashing or not working correctly
phaseshift
phaseshiftβ€’13mo ago
What is the exact 'null warning' that you get?
GIGA BRAIN
GIGA BRAINβ€’13mo ago
gimme a sec my code that was working all this time isn't working anymore System.Net.Http.HttpRequestException: 'Response status code does not indicate success: 503 (Unauthorized).' i'm now getting this when i run my program at this line of code // Get JSON results and deserialize var citySearch = await client.GetFromJsonAsync<List<Root>>(link);
daysleeper
daysleeperβ€’13mo ago
authorize
phaseshift
phaseshiftβ€’13mo ago
maybe your apikey is rate limited
GIGA BRAIN
GIGA BRAINβ€’13mo ago
aw man no way i forgot about that so it says 50 calls a day so if i've run my program 50 times that means all my calls are gone?
phaseshift
phaseshiftβ€’13mo ago
yup
GIGA BRAIN
GIGA BRAINβ€’13mo ago
NOOOOO hold on im gonna get another key
phaseshift
phaseshiftβ€’13mo ago
suggest you then save the json data to local file πŸ˜„
GIGA BRAIN
GIGA BRAINβ€’13mo ago
oh yeah i never thought about that haha
GIGA BRAIN
GIGA BRAINβ€’13mo ago
GIGA BRAIN
GIGA BRAINβ€’13mo ago
here it is oh i see, so i can bypass the exception and write out whatever the value is still? but if its null wouldn't it just be nothing
daysleeper
daysleeperβ€’13mo ago
no here it throws an exception not a warning
GIGA BRAIN
GIGA BRAINβ€’13mo ago
oh my bad, i said it was a null warning i thought they were the same thing
phaseshift
phaseshiftβ€’13mo ago
weatherResult being null means the json doesnt match the binding class - DailyForecast
GIGA BRAIN
GIGA BRAINβ€’13mo ago
oh so there IS something wrong with my property class ok i'll look into that some more
phaseshift
phaseshiftβ€’13mo ago
you can paste the json here,https://quicktype.io/, or directly into visual studio, to get c# classes to match the json
Vi Ness
Vi Nessβ€’13mo ago
The warning is the compiler telling you "Hey, this could be null but it prob'ly shouldn't be," warning you that there could be an exception. The exception is the runtime saying "This is null and I don't like it"
GIGA BRAIN
GIGA BRAINβ€’13mo ago
yeah i got one, someone recommended json2csharp.com i'm following the format, but i guess i did something wrong ah ok, so the warning leads to the exception
Vi Ness
Vi Nessβ€’13mo ago
It just means that there could be an exception
GIGA BRAIN
GIGA BRAINβ€’13mo ago
oh i see what i did wrong now i completely forgot there was another sub-property in maximum and minimum πŸ€¦β€β™‚οΈ wait im not sure anymore
GIGA BRAIN
GIGA BRAINβ€’13mo ago
GIGA BRAIN
GIGA BRAINβ€’13mo ago
this is what the documentation says
GIGA BRAIN
GIGA BRAINβ€’13mo ago
GIGA BRAIN
GIGA BRAINβ€’13mo ago
and this is what the converter recommends based off the json file this DOES mean that i need 2 more classes for minimum and maximum right?
Vi Ness
Vi Nessβ€’13mo ago
The exception makes it sound like it's the Temperature object that didn't get deserialized correctly. Did the date print out correctly when you ran it?
GIGA BRAIN
GIGA BRAINβ€’13mo ago
yeah i think im starting to get it i need to struggle with it a little more but yeah i think the temperature object is the problem
Vi Ness
Vi Nessβ€’13mo ago
The first thing I would try is changing the Value properties on Minimum and Maximum (realistically they should be the same class) to double instead of int. The values in the Json have decimal points so idk why the converter recommends int.
GIGA BRAIN
GIGA BRAINβ€’13mo ago
i'm stumped, i thought i had it but i guess i didn't i've been trying to figure this out for a while but i just cant seem to get it right i changed up my classes to reflect the documentation and the json class converter, but i can't access any of the results
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WeatherApp
{
public class newRoot
{
public List<DailyForecast> DailyForecasts { get; set; }
}

public class DailyForecast
{
public string Date { get; set; }
public Temperature Temperature { get; set; }
}

public class Maximum
{
public double Value { get; set; }
public string Unit { get; set; }
}

public class Minimum
{
public double Value { get; set; }
public string Unit { get; set; }
}

public class Temperature
{
public Minimum Minimum { get; set; }
public Maximum Maximum { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WeatherApp
{
public class newRoot
{
public List<DailyForecast> DailyForecasts { get; set; }
}

public class DailyForecast
{
public string Date { get; set; }
public Temperature Temperature { get; set; }
}

public class Maximum
{
public double Value { get; set; }
public string Unit { get; set; }
}

public class Minimum
{
public double Value { get; set; }
public string Unit { get; set; }
}

public class Temperature
{
public Minimum Minimum { get; set; }
public Maximum Maximum { get; set; }
}
}
GIGA BRAIN
GIGA BRAINβ€’13mo ago
GIGA BRAIN
GIGA BRAINβ€’13mo ago
i keep getting this error in the code but in the documentation the api i'm calling says it returns an array, and i was able to turn the json into a list previously I've tried using var weatherResult = await client.GetStringAsync(link); and printing out weatherResult, but then my program won't even run due to build errors
Vi Ness
Vi Nessβ€’13mo ago
I see you removed the &q={cityInput} from your link and the int UnitType from the Minimum and Maximum classes. Is that right?
GIGA BRAIN
GIGA BRAINβ€’13mo ago
well i plan on adding back cityInput later when i get the json deserialization and printing all correct and i did remove the int UnitType
Vi Ness
Vi Nessβ€’13mo ago
Ah okay, so the API still returns a json if you don't provide a city?
GIGA BRAIN
GIGA BRAINβ€’13mo ago
i removed stuff i didn't want from the json so in this link http://dataservice.accuweather.com/forecasts/v1/daily/5day/2178895?apikey= the 2178895 is the location key i'm able to get from
var link = $"http://dataservice.accuweather.com/locations/v1/cities/search?apikey={key}&q={cityInput}";

// Get JSON results and deserialize
var citySearch = await client.GetFromJsonAsync<List<Root>>(link);

// Print results
foreach (Root root in citySearch)
{
Console.WriteLine($"\nCity key: {root.Key}");
Console.WriteLine($"{root.EnglishName}, {root.AdministrativeArea.EnglishName}, {root.PrimaryPostalCode}");
Console.WriteLine($"Timezone: {root.TimeZone.Name}");
Console.WriteLine($"Latitude: {root.GeoPosition.Latitude} Longitude: {root.GeoPosition.Longitude}");
}
var link = $"http://dataservice.accuweather.com/locations/v1/cities/search?apikey={key}&q={cityInput}";

// Get JSON results and deserialize
var citySearch = await client.GetFromJsonAsync<List<Root>>(link);

// Print results
foreach (Root root in citySearch)
{
Console.WriteLine($"\nCity key: {root.Key}");
Console.WriteLine($"{root.EnglishName}, {root.AdministrativeArea.EnglishName}, {root.PrimaryPostalCode}");
Console.WriteLine($"Timezone: {root.TimeZone.Name}");
Console.WriteLine($"Latitude: {root.GeoPosition.Latitude} Longitude: {root.GeoPosition.Longitude}");
}
the api i'm using (accuweather) has a flowchart where it says to get the city key from the location api and then use that city key to call the forecast api where i can get the weather the current flow of my program is able to get the city's general information as seen in the foreach loop and since there are multiple cities with the same name in different countries, i'll have the user enter in their desired city key which will then output all the weather but im having trouble with accessing the weather in the first palce i thought it would be as simple as this code i just posted since in the documentation it says they both return an array
GIGA BRAIN
GIGA BRAINβ€’13mo ago
GIGA BRAIN
GIGA BRAINβ€’13mo ago
GIGA BRAIN
GIGA BRAINβ€’13mo ago
my current thought process is that my problem is stemming from my newRoot class, where it's a list of the DailyForecast type called DailyForecasts honestly idk, im just stumped
Vi Ness
Vi Nessβ€’13mo ago
I'd start with just trying to get the json string from the api into the console as text to make sure you're calling the api correctly. Once you have that working we can focuus on deserializing them
GIGA BRAIN
GIGA BRAINβ€’13mo ago
and i would do that through GetStringAsync right?
link = $"http://dataservice.accuweather.com/forecasts/v1/daily/5day/2178895?apikey={key}";

var weatherResult = await client.GetStringAsync(link);

Console.WriteLine(weatherResult);
link = $"http://dataservice.accuweather.com/forecasts/v1/daily/5day/2178895?apikey={key}";

var weatherResult = await client.GetStringAsync(link);

Console.WriteLine(weatherResult);
when i try to run this code, my app won't even run at all, saying there were build errors
Vi Ness
Vi Nessβ€’13mo ago
What are the build errors?
GIGA BRAIN
GIGA BRAINβ€’13mo ago
nevermind im dumb i didn't see that i didnt comment out a curly brace
GIGA BRAIN
GIGA BRAINβ€’13mo ago
GIGA BRAIN
GIGA BRAINβ€’13mo ago
yup im able to get the json this doesn't look like an array straight up to me
Vi Ness
Vi Nessβ€’13mo ago
It looks like there's a Headline and then an array of DailyForecasts
GIGA BRAIN
GIGA BRAINβ€’13mo ago
do i need to include headline in my property class? i was told that i could omit properties that i didn't plan on including in my classes when dealing with apis
Vi Ness
Vi Nessβ€’13mo ago
You can omit them, yeah. I've only dealt with deserialization with Newtonsoft.Json and making my models like this where you specify what each thing is called in the json file
GIGA BRAIN
GIGA BRAINβ€’13mo ago
ooh i see i've heard about newtonsoft.json, is it widely used? maybe i should switch over to that
Vi Ness
Vi Nessβ€’13mo ago
I think it's one of, if not the most downloaded nuget package
GIGA BRAIN
GIGA BRAINβ€’13mo ago
would i run into the same problem i'm having right now even if i used newtson soft though? surely this is a logic problem im just not understanding
Vi Ness
Vi Nessβ€’13mo ago
Prob'ly. I was just sharing what I have experience with
GIGA BRAIN
GIGA BRAINβ€’13mo ago
fair, definitely gonna look into that later
GIGA BRAIN
GIGA BRAINβ€’13mo ago
looking at the json in the formatter, i can see that dailyforecast is indeed an array
GIGA BRAIN
GIGA BRAINβ€’13mo ago
and it would seem that my classes are correct according to the converter, also taking into account making changes according to the documentation of the api
Vi Ness
Vi Nessβ€’13mo ago
What happens if you try to deserialize it now?
GIGA BRAIN
GIGA BRAINβ€’13mo ago
so just to make sure,
var weatherResult = await client.GetFromJsonAsync<List<newRoot>>(link);
var weatherResult = await client.GetFromJsonAsync<List<newRoot>>(link);
this line of code makes sense right?
public class newRoot
{
public List<DailyForecast> DailyForecasts { get; set; }
}
public class newRoot
{
public List<DailyForecast> DailyForecasts { get; set; }
}
referencing this ^
Vi Ness
Vi Nessβ€’13mo ago
Shouldn't there be only one newRoot? Or is it giving you multiple in one call?
GIGA BRAIN
GIGA BRAINβ€’13mo ago
yeah i only have one newRoot
GIGA BRAIN
GIGA BRAINβ€’13mo ago
GIGA BRAIN
GIGA BRAINβ€’13mo ago
if i run that code i get this
Vi Ness
Vi Nessβ€’13mo ago
You're trying to deserialize it into a List<newRoot>
GIGA BRAIN
GIGA BRAINβ€’13mo ago
yup
Vi Ness
Vi Nessβ€’13mo ago
But there's only one
GIGA BRAIN
GIGA BRAINβ€’13mo ago
huh? im confused
Vi Ness
Vi Nessβ€’13mo ago
GetFromJsonAsync<List<newRoot>(link) means you're trying to read an array of newRoot from the string. But the string is not an array of newRoot, it's only one
GIGA BRAIN
GIGA BRAINβ€’13mo ago
i think i get what youre trying to say? so in this case, when im using <List<newRoot>>: i'm assuming that the entire json ouput is an array when in reality it isn't entirely an array?
Vi Ness
Vi Nessβ€’13mo ago
Right. The only array part of the Json is the DailyForecasts, which are part of newRoot
GIGA BRAIN
GIGA BRAINβ€’13mo ago
aiya so then i need to figure out how to deserialize the whole thing
Vi Ness
Vi Nessβ€’13mo ago
You need to figure out how to derserialize the one thing
GIGA BRAIN
GIGA BRAINβ€’13mo ago
and by one thing do you mean the json output?
Vi Ness
Vi Nessβ€’13mo ago
I mean the newRoot
GIGA BRAIN
GIGA BRAINβ€’13mo ago
isn't it not just a matter of removing the <list>?
Vi Ness
Vi Nessβ€’13mo ago
It is exactly that
GIGA BRAIN
GIGA BRAINβ€’13mo ago
then i have the newRoot object that is retrieved and deserialized NICE
Vi Ness
Vi Nessβ€’13mo ago
You're only trying to read one newRoot, not a list of them
GIGA BRAIN
GIGA BRAINβ€’13mo ago
and again i know that its only ONE newRoot since the entire output isn't an array?
Vi Ness
Vi Nessβ€’13mo ago
Yeah
GIGA BRAIN
GIGA BRAINβ€’13mo ago
got it so now i just need to output the result when i run the code with console.WriteLine(weatherResult.DailyForecasts)
GIGA BRAIN
GIGA BRAINβ€’13mo ago
GIGA BRAIN
GIGA BRAINβ€’13mo ago
i see that it's a list but when i try printing out the contents in a foreach loop, i can't do so
Vi Ness
Vi Nessβ€’13mo ago
Do you know how to set breakpoint and debug your variables?
GIGA BRAIN
GIGA BRAINβ€’13mo ago
yes and no? in this case would i set the breakpoint on this line?
var weatherResult = await client.GetFromJsonAsync<newRoot>(link);
var weatherResult = await client.GetFromJsonAsync<newRoot>(link);
and then just hover over it when it reaches that point to see the values?
Vi Ness
Vi Nessβ€’13mo ago
Since we know that it's not crashing, I'd set the breakpoint after that and inspect your weatherResult variable to see what's in it
GIGA BRAIN
GIGA BRAINβ€’13mo ago
got it yup the values are there let me try and get a sc
GIGA BRAIN
GIGA BRAINβ€’13mo ago
Vi Ness
Vi Nessβ€’13mo ago
That looks good. You've got 5 DailyForecasts in that array
GIGA BRAIN
GIGA BRAINβ€’13mo ago
i'm just confused why in the autocomplete it doesn't give me these options to add to the code yup the api i'm calling gets the forecast for 5 days WAIT do i just need to do Console.WriteLine(weatherResult.DailyForecasts[0]); ok amybe not it didnt work
Vi Ness
Vi Nessβ€’13mo ago
That'll prob'ly just output WeatherApp.DailyForecast
GIGA BRAIN
GIGA BRAINβ€’13mo ago
oh wait now the property options are coming up
Vi Ness
Vi Nessβ€’13mo ago
Mmhmm, cuz now you're accessing the DailyForecast that's in the List
GIGA BRAIN
GIGA BRAINβ€’13mo ago
IT WORKS it completely slipped my mind to access the array values but obviously i should've since it's an array lol THANK YOU VERY MUCH i appreciate all your help🀝
Vi Ness
Vi Nessβ€’13mo ago
Np, now you get to do fun stuff with all your weather data~
Accord
Accordβ€’13mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server
More Posts