Json-file (Api-Response) deserialized to C# Class works with Winforms/Console but I do get an Error with ASP.Net Blazor! Why?

I started looking into Openweathermap API (weather Data). The Api response is a Json file. I managed to get everything working with MS WinForms in (VisualStudio).

Now I wanted to do the same on my BlazorWebpage. But I cant get it to work. I am stuck maybe you could point me in the right direction.

In the Winforms project I succsessfull call the Api with this code:

    private async Task CallWeatherApiAsync()
    {
        oneDayWeatherInfo = new OneDayWeatherDataModel();
        using (HttpResponseMessage response = await client.GetAsync(client.BaseAddress))
        {
            if (response.IsSuccessStatusCode)
            {
                oneDayWeatherInfo= await response.Content.ReadAsAsync<OneDayWeatherDataModel>(); 
            }
        }
     }

Everything from the api response data “goes” in the right places. The WeatherDataModel is the C# Class structur “from” the jsonfile. The Classes looking like this (on first read skip this):

namespace Blazor_WeatherApi.Models
{
public class OneDayWeatherDataModel
{
    //Name of the City
    public string Name { get; set; }

    public Main Main { get; set; }

    public Coord Coord { get; set; }
    public List<Weather> Weather { get; set; }
    public Wind Wind { get; set; }

    public Clouds Clouds { get; set; }
    public Sys Sys { get; set; }

    public int Visibility { get; set; }
    public int Dt { get; set; }
    public int Timezone { get; set; }
    public int Id { get; set; }
    public int Cod { get; set; }
}

public class Main
{
    public double Temp { get; set; }
    public double Feels_like { get; set; }
    public double Temp_min { get; set; }
    public double Temp_max { get; set; }
    public int Pressure { get; set; }
    public int Humidity { get; set; }
}

public class Coord
{
    public double Lon { get; set; }
    public double Lat { get; set; }
}

public class Weather
{
    public int Id { get; set; }
    public string Main { get; set; }
    public string Description { get; set; }
    public string Icon { get; set; }
}

public class Wind
{
    public double Speed { get; set; }
    public int Deg { get; set; }
    public double Gust { get; set; }
}

public class Clouds
{
    public int All { get; set; }
}

public class Sys
{
    public int Type { get; set; }
    public int Id { get; set; }
    public double Message { get; set; }
    public string Country { get; set; }
    public int Sunrise { get; set; }
    public int Sunset { get; set; }
}
}

Now to my problem I created a blazor project and I can call the data from the root ModelClass like Name (first Propertie in the class Model)
But I cant use anything else that is one class deeper besides root class. E.g. If I want to get the temperatur value root->Main->Temp then I get an error.
I used the same ClassModel in the winforms project there it was successful.

Here the Blazor code that works only for the Properties from the “root class”:

@page "/weather"
@inject HttpClient http;

<h3>ApiCall</h3>

 <button class="btn btn-primary" @onclick="@GetWeatherData">Get Weather</button>

 <table>

    <tr>
       <td>@weatherModel.Name</td>
    </tr>
    <tr>
       <td>@weatherModel.Dt</td>
    </tr>
   @*<tr>
        <td>@weatherModel.Main.Temp</td>       // IF I DECOMMENT THIS 3 LINES I GET the ERROR
    </tr>*@
  </table>

@code {
   OneDayWeatherDataModel weatherModel = new OneDayWeatherDataModel();

    private async Task GetWeatherData()
    {
      weatherModel = await http.GetJsonAsync<OneDayWeatherDataModel> 
       ("https://api.openweathermap.org/data/2.5/weather?id=...");
    }
 }

If I comment the 3 lines out I have a working blazer api call and I get the name of the city from the web-api-call from openweathermap. BUT…

The Error occures when I decomment @weatherModel.Main.Temp the project freezes an Visual Studio tells me it is in HoldModus
(System.NullReferenceException: “Object reference not set to an instance of an object.”)

This happens at the moment I browse to the page NOT after I click the button ??? Any idea what I did wrong? And sorry that the post is so long and intertwined 🙂

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The problem is that you are manually instantiating the class in the following line and not setting the ‘Main’ property to anything, and therfore it is null

OneDayWeatherDataModel weatherModel = new OneDayWeatherDataModel();

You could ensure that you populate the property or use access it with the following to avoid the null reference error:

    <td>@weatherModel?.Main?.Temp</td>

However you might also want to consider something like the below so that that table doesnt show unless it’s got the data from the API:

@if (weatherModel != null) {
<table>

    <tr>
       <td>@weatherModel.Name</td>
    </tr>
    <tr>
       <td>@weatherModel.Dt</td>
    </tr>
   <tr>
        <td>@weatherModel.Main.Temp</td>       
    </tr>
  </table>
}

@code {
   OneDayWeatherDataModel weatherModel = null;

    private async Task GetWeatherData()
    {
      weatherModel = await http.GetJsonAsync<OneDayWeatherDataModel> 
       ("https://api.openweathermap.org/data/2.5/weather?id=...");
    }
 }


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x