nogood
nogood

Reputation: 1320

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 :)

Upvotes: 0

Views: 261

Answers (1)

App Pack
App Pack

Reputation: 1532

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=...");
    }
 }

Upvotes: 1

Related Questions