简体   繁体   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>

Error occurs on line线上出现错误

MyWeatherData = WeatherAPI.GetMyWeather();

Error:错误:

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

I never used MVC before and I am getting confused on flow of MVC.我以前从未使用过 MVC,我对 MVC 的流程感到困惑。 Currently, from view , I am calling HomeController .目前,从view ,我正在调用HomeController Then from HomeController , I am calling 2nd WeatherController .然后从HomeController ,我打电话给 2nd WeatherController I know this is wrong but now sure how to do this without creating so many controllers我知道这是错误的,但现在确定如何在不创建这么多控制器的情况下执行此操作

What I am trying to do: I have a view (index), where I have a button.我想做什么:我有一个视图(索引),其中有一个按钮。 If button is clicked, I want to use the weather API to get the data, save in model class, and display the data in a view ( index ).如果单击按钮,我想使用天气 API 获取数据,保存在 model class 中,并在视图( index )中显示数据。

Index.cshtml file: this view has a button. Index.cshtml文件:这个视图有一个按钮。 if you click on it, it will send a post request to HomeController如果你点击它,它会向HomeController发送一个 post 请求

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

HomeController class家庭控制器 class

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

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

WeatherController class天气控制器 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 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; }
}

MyWeatherData is type of WeatherModel while the return type of GetMyWeather is Task<IActionResult> . MyWeatherDataWeatherModel的类型,而GetMyWeather的返回类型是Task<IActionResult> That is why you get such compilation error.这就是为什么你会得到这样的编译错误。

Change your code like below:像下面这样更改您的代码:

HomeController家庭控制器

Note: you need initialize the WeatherController , otherwise you will get the null exception when you run the code.注意:您需要初始化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();
}

WeatherController天气控制器

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

Some suggestion一些建议

1.No need set the value for each property of the WeatherModel WM = new WeatherModel(); 1.无需为WeatherModel WM = new WeatherModel(); , the data rawWeather you get is actually a type of WeatherModel . ,你得到的数据rawWeather实际上是一种WeatherModel Just change your code:只需更改您的代码:

[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; 2. var latitude = 40.712776; , var longitude = -74.005974; , var longitude = -74.005974; are type of long and hourly is string type, be sure the api you called by HttpClient should contain parameter with ( long latitude, long longitude, string hourly ).long的类型, hourly是字符串类型,确保你调用的 HttpClient 的 api 应该包含参数 with ( long latitude, long longitude, string hourly )。 If the type does not match, you will get the 400 error.如果类型不匹配,您将收到 400 错误。

For example:例如:

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

You're asking a few different questions here but it seems like ultimately you want to know how to resolve the compilation issue.您在这里问了几个不同的问题,但似乎最终您想知道如何解决编译问题。

As you can see in your WeatherController action, it is async which is indicated by the async keyword as well as the Task type.正如您在WeatherController操作中看到的那样,它是异步的,由async关键字和Task类型指示。

public async Task<IActionResult> GetMyWeather()

Task<IActionResult> means that you must await the response in order to get the response of type IActionResult . Task<IActionResult>意味着您必须等待响应才能获得IActionResult类型的响应。 In order to do this, you should change your HomeController action to be async as well:为此,您还应该将 HomeController 操作更改为异步操作:

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

暂无
暂无

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

相关问题 ASP.NET Core Web API - 无法隐式转换类型&#39;System.Threading.Tasks.Task<Merchant?> &#39;到&#39;商人&#39; - ASP.NET Core Web API - Cannot implicitly convert type 'System.Threading.Tasks.Task<Merchant?>' to 'Merchant' 无法将类型“Microsoft.AspNetCore.Mvc.NotFoundResult”隐式转换为“System.Threading.Tasks.Task” - Cannot implicitly convert type 'Microsoft.AspNetCore.Mvc.NotFoundResult' to 'System.Threading.Tasks.Task' 无法转换类型'System.Threading.Tasks.Task<microsoft.aspnetcore.mvc.iactionresult> ' 到 'Microsoft.AspNetCore.Mvc.OkObjectResult'</microsoft.aspnetcore.mvc.iactionresult> - Cannot convert type 'System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult>' to 'Microsoft.AspNetCore.Mvc.OkObjectResult' 无法将类型'System.Threading.Tasks.Task <System.Web.Mvc.ActionResult>'隐式转换为'System.Web.Mvc.ActionResult' - Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Web.Mvc.ActionResult>' to 'System.Web.Mvc.ActionResult' 无法将类型&#39;bool&#39;隐式转换为&#39;System.Threading.Tasks.Task&#39; - Cannot implicitly convert type 'bool' to 'System.Threading.Tasks.Task' 无法将类型&#39;void&#39;隐式转换为&#39;System.Threading.Tasks.Task&#39; - Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task' 无法隐式转换类型&#39;System.Threading.Tasks.Task - Cannot implicitly convert type 'System.Threading.Tasks.Task 无法将类型“System.Web.Mvc.ViewResult”隐式转换为“Microsoft.AspNetCore.Mvc.IActionResult”-Asp.Net MVC 5 - Cannot implicitly convert type 'System.Web.Mvc.ViewResult' to 'Microsoft.AspNetCore.Mvc.IActionResult' - Asp.Net MVC 5 ASP.NET Core 6“无法将类型'Rotativa.ViewAsPdf'隐式转换为'Microsoft.AspNetCore.Mvc.ActionResult'” - ASP.NET Core 6 "Cannot implicitly convert type 'Rotativa.ViewAsPdf' to 'Microsoft.AspNetCore.Mvc.ActionResult'" 无法将类型&#39;System.Collections.Generic.List &lt;&gt;&#39;隐式转换为&#39;System.Threading.Tasks.Task &lt;&gt;&gt; - Cannot implicitly convert type 'System.Collections.Generic.List<>' to 'System.Threading.Tasks.Task<>>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM