繁体   English   中英

简单 ASP.NET 核心 Web API - 无法隐式转换类型 system.threading.tasks.task<microsoft.aspnetcore.mvc.iaction></microsoft.aspnetcore.mvc.iaction>

[英]Simple ASP.NET Core Web API - cannot implicitly convert type system.threading.tasks.task<microsoft.aspnetcore.mvc.IAction>

线上出现错误

MyWeatherData = WeatherAPI.GetMyWeather();

错误:

无法隐式转换类型 System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IAction>

我以前从未使用过 MVC,我对 MVC 的流程感到困惑。 目前,从view ,我正在调用HomeController 然后从HomeController ,我打电话给 2nd WeatherController 我知道这是错误的,但现在确定如何在不创建这么多控制器的情况下执行此操作

我想做什么:我有一个视图(索引),其中有一个按钮。 如果单击按钮,我想使用天气 API 获取数据,保存在 model class 中,并在视图( index )中显示数据。

Index.cshtml文件:这个视图有一个按钮。 如果你点击它,它会向HomeController发送一个 post 请求

<form asp-controller="Home" method="post">
        <button type="submit" >Submit</button>
</form>
// Display weather data here on click 

家庭控制器 class

    public WeatherModel MyWeatherData { get; set; } = default!;
    public WeatherController WeatherAPI { get; set;  }

    public IActionResult Index()
    {
        MyWeatherData = WeatherAPI.GetMyWeather();
        return View();
    }

天气控制器 class

[Route("api/[controller]")]
[ApiController]
public class WeatherController : ControllerBase
{
    [HttpGet]
    public async Task<IActionResult> GetMyWeather()
    {
        var latitude = 40.712776;
        var longitude = -74.005974;

        using (var client = new HttpClient())
        {
            try
            {
                client.BaseAddress = new Uri("https://api.open-meteo.com");
                var response = await client.GetAsync($"/v1/forecast?latitude={latitude}&longitude={longitude}&hourly=temperature_2m");
                response.EnsureSuccessStatusCode();

                var stringResult = await response.Content.ReadAsStringAsync(); //get json data in string 
                var rawWeather = JsonConvert.DeserializeObject<WeatherModel>(stringResult);

                WeatherModel WM = new WeatherModel();
                WM.latitude = rawWeather.latitude;
                WM.longitude = rawWeather.longitude;
                WM.generationtime_ms = rawWeather.generationtime_ms;
                WM.utc_offset_seconds = rawWeather.utc_offset_seconds;
                WM.timezone = rawWeather.timezone;
                WM.timezone_abbreviation = rawWeather.timezone_abbreviation;
                WM.elevation = rawWeather.elevation;
                
                return Ok(WM);
            }
            catch (HttpRequestException httpRequestException)
            {
                return BadRequest($"Error getting weather from OpenWeather: {httpRequestException.Message}");
            }
    }
}  //end of method 

Model class

public class WeatherModel
{
    public long latitude { get; set; }
    public long longitude { get; set; }
    public long generationtime_ms { get; set; }
    public long utc_offset_seconds { get; set; }

    public string timezone { get; set; }
    public string timezone_abbreviation { get; set; }
    public string elevation { get; set; }
}

MyWeatherDataWeatherModel的类型,而GetMyWeather的返回类型是Task<IActionResult> 这就是为什么你会得到这样的编译错误。

像下面这样更改您的代码:

家庭控制器

注意:您需要初始化WeatherController ,否则在运行代码时会出现 null 异常。

public WeatherModel MyWeatherData { get; set; } = default!;
public WeatherController WeatherAPI { get; set; } = new WeatherController(); //change here....

public async Task<IActionResult> Index()
{
    MyWeatherData = await WeatherAPI.GetMyWeather();  //add await...
    return View();
}

天气控制器

[Route("api/[controller]")]
[ApiController]
public class WeatherController : ControllerBase
{
    [HttpGet]
    public async Task<WeatherModel> GetMyWeather()  //change the type to `Task<WeatherModel>`
    {
        var latitude = 40.712776;
        var longitude = -74.005974;

        using (var client = new HttpClient())
        {
            try
            {
                //...
                return WM;  //change here...
            }
            catch (HttpRequestException httpRequestException)
            {    
                //also change here...
                throw new Exception($"Error getting weather from OpenWeather: {httpRequestException.Message}");   
            }
        }
    }  
}

一些建议

1.无需为WeatherModel WM = new WeatherModel(); ,你得到的数据rawWeather实际上是一种WeatherModel 只需更改您的代码:

[HttpGet]
public async Task<WeatherModel> GetMyWeather()
{
    var latitude = 40.712776;
    var longitude = -74.005974;

    using (var client = new HttpClient())
    {
        try
        {
            client.BaseAddress = new Uri("https://api.open-meteo.com");
            var response = await client.GetAsync($"/v1/forecast?latitude={latitude}&longitude={longitude}&hourly=temperature_2m");
            response.EnsureSuccessStatusCode();

            var stringResult = await response.Content.ReadAsStringAsync(); //get json data in string 
            var rawWeather = JsonConvert.DeserializeObject<WeatherModel>(stringResult);

            return rawWeather;   //just return rawWeather....
        }
        catch (HttpRequestException httpRequestException)
        {
            throw new Exception($"Error getting weather from OpenWeather: {httpRequestException.Message}");
        }
    }
}  

2. var latitude = 40.712776; , var longitude = -74.005974; long的类型, hourly是字符串类型,确保你调用的 HttpClient 的 api 应该包含参数 with ( long latitude, long longitude, string hourly )。 如果类型不匹配,您将收到 400 错误。

例如:

[Route("/v1/forecast")]
public IActionResult Get(double latitude, double longitude,string hourly)
{
    var model = new WeatherModel()
    {
        latitude = Convert.ToInt64(latitude),
        longitude = Convert.ToInt64(longitude),
        //...
    };
    return Json(model);
}

您在这里问了几个不同的问题,但似乎最终您想知道如何解决编译问题。

正如您在WeatherController操作中看到的那样,它是异步的,由async关键字和Task类型指示。

public async Task<IActionResult> GetMyWeather()

Task<IActionResult>意味着您必须等待响应才能获得IActionResult类型的响应。 为此,您还应该将 HomeController 操作更改为异步操作:

public async Task<IActionResult> Index()
{
    MyWeatherData = await WeatherAPI.GetMyWeather();
    return View();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM