You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET调用天气API报错:非静态成员需要对象引用

错误产生原因

你遇到的报错由3个代码逻辑问题共同导致:

  • 模型定义逻辑错误:你将Current、Location等实体类全部嵌套在WeatherApi类内部,但WeatherApi本身没有定义任何Current类型的实例属性。当你在视图中通过@model WeatherApi声明模型后,写Model.Current时编译器会认为你在访问嵌套类Current的类型本身(静态引用),而非实例对象的属性,直接访问类型上的实例属性Temperature就会触发“非静态字段、方法或属性需要对象引用”的错误。
  • 控制器反序列化类型不匹配:你在控制器中反序列化JSON时使用了未定义的WeatherApiResponse类型,和你自己写的模型结构完全不对应,最终传给视图的对象类型和视图声明的模型类型不一致。
  • 附加隐患:你在async标记的Action中调用GetAsync时使用了.Result做同步阻塞,容易引发线程池死锁,虽然不是本次报错的直接原因,但需要修正。
可行修复方案

按以下步骤逐段修正代码即可:

1. 重构模型层代码

去掉无意义的嵌套类结构,平级定义所有API返回对应的实体类,统一根返回类的命名和控制器里的调用对应:

using Newtonsoft.Json;

namespace Exercice.Models
{
    public class Current
    {
        [JsonProperty("observation_time")]
        public string ObservationTime { get; set; }
        [JsonProperty("temperature")]
        public int Temperature { get; set; }
        [JsonProperty("weather_code")]
        public int WeatherCode { get; set; }
        [JsonProperty("weather_icons")]
        public List<string> WeatherIcons { get; set; }
        [JsonProperty("weather_descriptions")]
        public List<string> WeatherDescriptions { get; set; }
        [JsonProperty("wind_speed")]
        public int WindSpeed { get; set; }
        [JsonProperty("wind_degree")]
        public int WindDegree { get; set; }
        [JsonProperty("wind_dir")]
        public string WindDir { get; set; }
        [JsonProperty("pressure")]
        public int Pressure { get; set; }
        [JsonProperty("precip")]
        public int Precip { get; set; }
        [JsonProperty("humidity")]
        public int Humidity { get; set; }
        [JsonProperty("cloudcover")]
        public int Cloudcover { get; set; }
        [JsonProperty("feelslike")]
        public int Feelslike { get; set; }
        [JsonProperty("uv_index")]
        public int UvIndex { get; set; }
        [JsonProperty("visibility")]
        public int Visibility { get; set; }
        [JsonProperty("is_day")]
        public string IsDay { get; set; }
    }

    public class Location
    {
        [JsonProperty("name")]
        public string Name { get; set; }
        [JsonProperty("country")]
        public string Country { get; set; }
        [JsonProperty("region")]
        public string Region { get; set; }
        [JsonProperty("lat")]
        public string Lat { get; set; }
        [JsonProperty("lon")]
        public string Lon { get; set; }
        [JsonProperty("timezone_id")]
        public string TimezoneId { get; set; }
        [JsonProperty("localtime")]
        public string Localtime { get; set; }
        [JsonProperty("localtime_epoch")]
        public int LocaltimeEpoch { get; set; }
        [JsonProperty("utc_offset")]
        public string UtcOffset { get; set; }
    }

    public class Request
    {
        [JsonProperty("type")]
        public string Type { get; set; }
        [JsonProperty("query")]
        public string Query { get; set; }
        [JsonProperty("language")]
        public string Language { get; set; }
        [JsonProperty("unit")]
        public string Unit { get; set; }
    }

    // 统一根返回类名,和控制器调用对应
    public class WeatherApiResponse
    {
        [JsonProperty("request")]
        public Request Request { get; set; }
        [JsonProperty("location")]
        public Location Location { get; set; }
        [JsonProperty("current")]
        public Current Current { get; set; }
    }
}

2. 修正控制器代码

替换不存在的反序列化类型,去掉同步阻塞的.Result写法,补充请求成功校验:

public async Task<IActionResult> Weather()
{
    string baseAddress = "http://api.weatherstack.com/";
    // 生产环境建议将HttpClient注册为单例复用,避免端口耗尽问题
    HttpClient client = new HttpClient();
    client.BaseAddress = new Uri(baseAddress);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    string path = "current?access_key=<MYACCESSKEY>&query=Madrid";
    // 用await异步等待请求,不要用.Result阻塞
    HttpResponseMessage response = await client.GetAsync(path);
    response.EnsureSuccessStatusCode();
    string myJsonResponse = await response.Content.ReadAsStringAsync();
    // 反序列化类型修正为实际定义的WeatherApiResponse
    WeatherApiResponse apiResponse = JsonConvert.DeserializeObject<WeatherApiResponse>(myJsonResponse);

    return View(apiResponse);
}

3. 修正视图层模型声明

将视图的模型类型替换为控制器实际传入的WeatherApiResponse:

@model Exercice.Models.WeatherApiResponse

<p>Temperature @Model.Current.Temperature&deg;</p>

改完之后重新编译运行即可正常获取并展示温度数据。

内容的提问来源于stack exchange,提问作者qwerty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 04:21:12