反序列化为C#类的Json文件(Api-Response)可以与Winforms/Console一起使用,但我在ASP中



我开始研究Openweathermap API(天气数据(。Api响应是一个Json文件。我设法在(VisualStudio(中使用MS WinForms使一切正常工作。

现在我想在我的BlazorWeb页面上做同样的事情。但是我不能让它工作。我被卡住了,也许你可以给我指一个正确的方向。

在Winforms项目中,我成功地调用了Api,代码是:

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

从api响应数据";转到";在正确的地方。WeatherDataModel是C#类结构;从";jsonfile。类看起来像这样(第一次阅读时跳过这个(:

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; }
}
}

现在我的问题是,我创建了一个blazor项目,我可以从根ModelClass调用类似Name的数据(类Model中的第一个Propertie(但是除了根类之外,我不能使用任何更深一个类的东西。例如,如果我想得到温度值根->Main->Temp,然后我得到一个错误。我在winforms项目中使用了相同的ClassModel,它很成功。

这里的Blazor代码仅适用于";根类":

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

如果我评论这3行,我有一个工作的blazer api调用,我从openweathermap的web api调用中获得城市的名称。但是。。。

当我停用@weatherModel时,会发生错误。主要的Temp项目冻结了一个Visual Studio,它告诉我它在HoldModus中(System.NullReferenceException:"对象引用未设置为对象的实例。"(

这种情况发生在我浏览页面的那一刻,而不是在我点击按钮之后???知道我做错了什么吗?很抱歉,这篇文章太长了,而且相互交织:(

问题是您在下面的行中手动实例化类,而没有将"Main"属性设置为任何值,因此它为空

OneDayWeatherDataModel weatherModel=新的OneDayWeather DataModel((;

您可以确保填充属性或使用以下内容访问它以避免空引用错误:

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

但是,您可能还需要考虑以下内容,以便该表不会显示,除非它从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=...");
}
}