簡體   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