【问题标题】:Consuming ASP.NET Web API REST Service in ASP.NET MVC using HttpClient使用 HttpClient 在 ASP.NET MVC 中使用 ASP.NET Web API REST 服务
【发布时间】:2020-12-02 23:07:49
【问题描述】:

我有一个 ASP.NET MVC 应用程序,我想从中使用 ASP.NET Web API REST 服务。 于是我找到了一段代码here。

在我的情况下,我想从我的 ASP.NET MVC 应用程序中的一个类中的方法调用 ASP.NET Web API 方法 (DumpIntoFile)(这个类不是控制器)。在对 DumpIntoFile 的调用完成并完成之前,我需要不继续执行。我该怎么做?我从未使用过 async 和 await,所以我完全不明白它们是如何工作的。

    public void GetData()
    {
         Warehouse myData = new Warehouse();
         myData.id = 1111;
         myData.name = blabla;

         string path = "c:\temp";
         string filename = "myData.dat";

         // Stuff here
         this.DumpWarehouseDataIntoFile(myData, path, filename);
         // Some other stuff here
    }

    public async void DumpWarehouseDataIntoFile(Warehouse myData, string path, string filename)  // See Warehouse class later in this post
    { 
        //Hosted web API REST Service base url  
        string Baseurl = "http://XXX.XXX.XX.X:YYYY/";  

        using (var client = new HttpClient())  
        {  
            //Passing service base url  
            client.BaseAddress = new Uri(Baseurl);  

            client.DefaultRequestHeaders.Clear();  
            //Define request data format  
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));  
              
            // Serialize parameter to pass to the asp web api rest service
            string jsonParam = Newtonsoft.JsonConvert.SerializeObject(myData);

            //Sending request to find web api REST service resource  using HttpClient

            // How can I pass parameters jsonParam, path and filename to below call??????? Concatenating it?
            HttpResponseMessage Res = await client.GetAsync("api/Warehouse/DumpIntoFile");  

            //Checking the response is successful or not which is sent using HttpClient  
            if (Res.IsSuccessStatusCode)  
            {  
               // Some other sftuff here
            }
         }
    }

仓库对象如下:

public class Warehouse {
    public Warehouse();

    public int id { get; set; }
    public string name { get; set; }
    
    // some other stuff here
}

以及带有方法的 web api 休息控制器:

public class MyWebApiController : ApiController
{
    public bool DumpIntoFile(string data, string path, string filename)
    {
        bool result;

        Warehouse myData = JsonConvert.DeserializeObject<Warehouse>(data);
        string myPath = path;
        string myFilename = filename;

        // Here rest of code

        return result;
    }
}

我也想在下面做:

  1. 避免对 URL 进行硬编码,因为如果 ASP.NET Web API REST 服务将来在另一台服务器上发布,那么我需要修改代码,更改它并再次发布我的 ASP.NET MVC 应用程序。也许将网址放在 web.config 文件中并从那里读取?
  2. 如何将参数jsonParam、路径和文件名传递给web api rest服务?连接它?

注意事项: 我正在使用 NET 4.5 和 Visual Studio 2013。

【问题讨论】:

  • 所以你的意思是await client.GetAsync("api/Warehouse/DumpIntoFile"); 不等待方法调用完成?你是什​​么意思? DumpIntoFile 中有什么内容?
  • @Dave 我已经更新了我的帖子。关于等待 client.GetAsync 我现在正在实现它,但我还没有能够测试它。我想知道 await 是否会等待并且不会继续执行下一行代码,直到对 web api rest 服务的调用完成并完成。我说的对吗?
  • Ralph(对不起,我无法在@提及中得到你的名字)-好的,是的,这应该等待请求完成。每当您使用 Async 方法时,您都需要等待它们,否则执行将不会等待 Async 方法完成。测试await client.GetAsync("api/Warehouse/DumpIntoFile"); 看看它是否在等待。如果您看到意外的输出,那么DumpIntoFile中会有一些未等待的内容@

标签: asp.net-mvc rest asp.net-web-api json.net dotnet-httpclient


【解决方案1】:

我该怎么做?我从未使用过 async 和 await,所以我完全不明白它们是如何工作的。

我建议您阅读我的async intro 并跟进async best practices。您将学到两个关键的东西:

  • 避免async void。
  • async/await 在您的代码库中“成长”是正常的。

在您的情况下,DumpWarehouseDataIntoFile 应该是 async Task 而不是 async void。这意味着GetData 需要await 从DumpWarehouseDataIntoFile 返回的任务。这意味着GetData 也应该是async Task。这意味着调用GetData 的东西应该使用await 等。

旁注:按照惯例,异步方法应以Async 结尾。

public async Task GetDataAsync()
{
  Warehouse myData = new Warehouse();
  myData.id = 1111;
  myData.name = blabla;

  string path = "c:\temp";
  string filename = "myData.dat";

  // Stuff here
  await this.DumpWarehouseDataIntoFileAsync(myData, path, filename);
  // Some other stuff here
}

public async Task DumpWarehouseDataIntoFileAsync(Warehouse myData, string path, string filename)

【讨论】:

  • 好的,正如你所说,这意味着调用GetData的东西应该使用await,等等。问题是链中涉及的所有方法都需要标记为异步并执行在调用的方法上等待。但是我调用 GetData 的方法没有标记为异步,所以这对我来说是个问题,如果我不将它标记为异步它不起作用。事实上我想要的是进行同步调用到 web api 休息服务方法 DumpIntoFile,不是异步调用。我需要等到 DumpIntoFile 完成并完成才能执行下一行代码。那么我该如何实现呢?
  • @Ralph:使其同步将使 线程 等待。使其(正确)异步将使 code 等待(不阻塞线程)。您可以将await 视为“异步等待”。所以“我需要等到 DumpIntoFile 完成并完成才能执行下一行代码”是通过使用 await 来完成的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多