请选择 进入手机版 | 继续访问电脑版

[MsSql] Blazor Server 应用程序中举行 HTTP 哀求

[复制链接]
查看187 | 回复37 | 2021-9-17 12:06:19 | 显示全部楼层 |阅读模式
目次

Blazor Server 应用程序中举行 HTTP 哀求

翻译自 Waqas Anwar 2021年5月4日的文章 《Making HTTP Requests in Blazor Server Apps》 [1]

Blazor Server 应用程序中举行
 HTTP 哀求

Blazor Server 应用利用 标准的 ASP.NET Core 应用程序,在服务端实行 .NET 代码。在 Blazor Server 应用程序中,我们可以像在 ASP.NET Core Web 应用程序中那样,利用 类似 的方式访问恣意 .NET 库或服务端功能。这此中 的一项功能是,利用 HTTP Client 实例向第三方 Web API 发送 HTTP 哀求 。在本教程中,我将向您展示创建 HTTP Client 实例的不同方法。别的 ,我还会向您展示怎样 在 Blazor Server 应用程序中利用 第三方 API 来获取和表现 数据。

下载源码[2]

一、第三方 Web API 概览

我们将开发 一个 Blazor Server 应用程序,该应用答应 用户在 Blazor 页面组件上输入国家代码和年份,然后我们将调用第三方 API 以获取指定国家和年份的公共假期列表。我们利用 的第三方 API 是Nager.Date[3],它是一个环球 公共假期 API。

这是一个非常简单的 API,您可以轻松地在 Postman 中输入以下 URL 测试此 API。

https://date.nager.at/api/v2/PublicHolidays/2021/CN

该 API 的相应 是 JSON 格式的公共假期列表,如下所示:

Blazor Server 应用程序中举行
 HTTP 哀求

二、从 Blazor Sever 应用程序开始

在 Visual Studio 2019 中创建一个 Blazor Server 应用程序,并新建一个名为 Models 的文件夹。在 Models 文件夹中添加以下两个模子 类,以映射上述 Holidays API 的哀求 和相应 。

HolidayRequestModel.cs

  1. public class HolidayRequestModel
  2. {
  3. public string CountryCode { get; set; }
  4. public int Year { get; set; }
  5. }
复制代码

HolidayResponseModel.cs

  1. public class HolidayResponseModel
  2. {
  3. public string Name { get; set; }
  4. public string LocalName { get; set; }
  5. public DateTime? Date { get; set; }
  6. public string CountryCode { get; set; }
  7. public bool Global { get; set; }
  8. }
复制代码

接下来,在 Pages 文件夹中创建一个新的 Razor 组件 HolidaysExplorer.razor 和代码埋伏 文件 HolidaysExplorer.razor.cs。假如 您想相识 有关 Razor 组件和代码埋伏 文件的更多知识,可以阅读文章《Blazor 组件入门指南》

HolidaysExplorer.razor.cs

  1. public partial class HolidaysExplorer
  2. {
  3. private HolidayRequestModel HolidaysModel = new HolidayRequestModel();
  4. private List<HolidayResponseModel> Holidays = new List<HolidayResponseModel>();
  5. [Inject]
  6. protected IHolidaysApiService HolidaysApiService { get; set; }
  7. private async Task HandleValidSubmit()
  8. {
  9. Holidays = await HolidaysApiService.GetHolidays(HolidaysModel);
  10. }
  11. }
复制代码

HolidaysModel 字段是 HolidayRequestModel 类的一个实例,它将帮助我们创建一个简单的表单来向用户扣问 国家代码和年份。下面的代码片断 表现 了利用 HolidaysModel 对象创建的 Blazor 表单,此中 HandleValidSubmit 方法是利用 Blazor Form OnValidSubmit 变乱 设置 的,用户提交表单时该方法将被调用。

  1. <EditForm Model="@HolidaysModel" OnValidSubmit="@HandleValidSubmit" class="form-inline">
  2. <label class="ml-2">Country Code:</label>
  3. <InputText id="CountryCode" @bind-Value="HolidaysModel.CountryCode" class="form-control" />
  4. <label class="ml-2">Year:</label>
  5. <InputNumber id="Year" @bind-Value="HolidaysModel.Year" class="form-control" />
  6. <button class="btn btn-primary ml-2" type="submit">Submit</button>
  7. </EditForm>
复制代码

Holidays 列表用来表现 从第三方 API 返回的假期。我们必要 利用 一个 @foreach 循环迭代返回的假期来天生 一个简单的 bootstrap 表格。

  1. @if (Holidays.Count > 0)
  2. {
  3. <table class="table table-bordered table-striped table-sm">
  4. <thead>
  5. <tr>
  6. <th>Date</th>
  7. <th>Name</th>
  8. <th>Local Name</th>
  9. <th>Country Code</th>
  10. <th>Global</th>
  11. </tr>
  12. </thead>
  13. <tbody>
  14. @foreach (var item in Holidays)
  15. {
  16. <tr>
  17. <td>@item.Date.Value.ToShortDateString()</td>
  18. <td>@item.Name</td>
  19. <td>@item.LocalName</td>
  20. <td>@item.CountryCode</td>
  21. <td>@item.Global</td>
  22. </tr>
  23. }
  24. </tbody>
  25. </table>
  26. }
复制代码

HolidaysExplorer.razor 视图的完备 代码如下:

  1. @page "/"
  2. <h3>Holidays Explorer</h3>
  3. <br />
  4. <EditForm Model="@HolidaysModel" OnValidSubmit="@HandleValidSubmit" class="form-inline">
  5. <label class="ml-2">Country Code:</label>
  6. <InputText id="CountryCode" @bind-Value="HolidaysModel.CountryCode" class="form-control" />
  7. <label class="ml-2">Year:</label>
  8. <InputNumber id="Year" @bind-Value="HolidaysModel.Year" class="form-control" />
  9. <button class="btn btn-primary ml-2" type="submit">Submit</button>
  10. </EditForm>
  11. <br />@if (Holidays.Count > 0)
  12. {
  13. <table class="table table-bordered table-striped table-sm">
  14. <thead>
  15. <tr>
  16. <th>Date</th>
  17. <th>Name</th>
  18. <th>Local Name</th>
  19. <th>Country Code</th>
  20. <th>Global</th>
  21. </tr>
  22. </thead>
  23. <tbody>
  24. @foreach (var item in Holidays)
  25. {
  26. <tr>
  27. <td>@item.Date.Value.ToShortDateString()</td>
  28. <td>@item.Name</td>
  29. <td>@item.LocalName</td>
  30. <td>@item.CountryCode</td>
  31. <td>@item.Global</td>
  32. </tr>
  33. }
  34. </tbody>
  35. </table>
  36. }
复制代码

此时假如 您运行该应用程序,您将看到一个不表现 任何假期的简单 HTML 表单。这是由于 方法 HandleValidSubmit 是空的,我们还未调用任何 API 来获取假期数据。

Blazor Server 应用程序中举行
 HTTP 哀求

三、在 Blazor Server 应用程序中利用 IHttpClientFactory 创建 HttpClient

在 Blazor Server 应用程序中利用 HttpClient 哀求 第三方 API 有多种不同的方式,让我们从一个基础的示例开始,在该示例中我们利用

  1. IHttpClientFactory
复制代码
创建
  1. HttpClient
复制代码
对象。

在项目中创建一个 Services 文件夹,并创建如下的 IHolidaysApiService 接口。该接口只有一个方法 GetHolidays,它以 HolidayRequestModel 作为参数并返回 HolidayResponseModel 对象的列表。

IHolidaysApiService.cs

  1. public interface IHolidaysApiService
  2. {
  3. Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest);
  4. }
复制代码

接下来,在 Services 文件夹中创建一个 HolidaysApiService 类,实现上面的接口。

  1. public class HolidaysApiService : IHolidaysApiService
  2. {
  3. private readonly IHttpClientFactory _clientFactory;
  4. public HolidaysApiService(IHttpClientFactory clientFactory)
  5. {
  6. _clientFactory = clientFactory;
  7. }
  8. public async Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest)
  9. {
  10. var result = new List<HolidayResponseModel>();
  11. var url = string.Format("https://date.nager.at/api/v2/PublicHolidays/{0}/{1}",
  12. holidaysRequest.Year, holidaysRequest.CountryCode);
  13. var request = new HttpRequestMessage(HttpMethod.Get, url);
  14. request.Headers.Add("Accept", "application/vnd.github.v3+json");
  15. var client = _clientFactory.CreateClient();
  16. var response = await client.SendAsync(request);
  17. if (response.IsSuccessStatusCode)
  18. {
  19. var stringResponse = await response.Content.ReadAsStringAsync();
  20. result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse,
  21. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  22. }
  23. else
  24. {
  25. result = Array.Empty<HolidayResponseModel>().ToList();
  26. }
  27. return result;
  28. }
  29. }
复制代码

在上面的 GetHolidays 方法中,我们起首 为第三方 API 创建了一个 URL,并将国家代码和年份参数添加到 URL 中。

  1. var url = string.Format("<a rel="external nofollow" target="_blank" href="https://date.nager.at/api/v2/PublicHolidays/%7B0%7D/%7B1">https://date.nager.at/api/v2/PublicHolidays/{0}/{1</a>}", holidaysRequest.Year, holidaysRequest.CountryCode);
复制代码

接下来,我们创建了 HttpRequestMessage 对象并设置 它以向第三方 API URL 发送 HTTP GET 哀求 。

  1. var request = new HttpRequestMessage(HttpMethod.Get, url);<br />
  2. request.Headers.Add("Accept", "application/vnd.github.v3+json");
复制代码

可以利用 依靠 注入 (DI) 哀求 一个 IHttpClientFactory,这正是我们将其注入到前面类的构造函数的缘故原由 。下面这行代码利用 IHttpClientFactory 创建了一个 HttpClient 实例。

  1. var client = _clientFactory.CreateClient();
复制代码

有了 HttpClient 对象之后,我们简单地调用它的 SendAsync 方法来发送一个 HTTP GET 哀求 。

  1. var response = await client.SendAsync(request);
复制代码

假如 API 调用成功,我们利用 下面这行代码将其相应 读取为字符串。

  1. var stringResponse = await response.Content.ReadAsStringAsync();
复制代码

末了 ,我们利用 JsonSerializer 类的 Deserialize 方法反序列化该相应 。

  1. result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse, <br />
  2.    new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
复制代码

在测试该应用程序之前,我们必要 在 Startup.cs 文件中注册 HolidaysApiService 服务。我们还必要 调用 AddHttpClient 方法注册 IHttpClientFactory。

Startup.cs

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddRazorPages();
  4. services.AddServerSideBlazor();
  5. services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
  6. services.AddHttpClient();
  7. }
复制代码

运行应用程序并在文本框中提供恣意 国家代码和年份。点击 Submit 按钮就会在后台调用我们的 GetHolidays 方法,然后您应该能看到如下所示的公共假期列表。

Blazor Server 应用程序中举行
 HTTP 哀求

四、在 Blazor Server 应用程序中创建定名 HttpClient 对象

上面的示例实用 于您正在重构现有的应用程序,盼望 在不影响整个应用程序的环境 下,在某些方法中利用 IHttpClientFactory 创建 HttpClient 对象的场景。假如 您要创建一个全新的应用程序,或者您想要将创建 HttpClient 对象的方式集中化,那么您必须利用 定名 HttpClient。

下面是创建定名 HTTP 客户端的好处:

  1. 我们可以为每个 HttpClient 定名 ,并在应用程序启动时指定与 HttpClient 相干 的全部 设置 ,而不是将设置 分散在整个应用程序当中。
  2. 我们可以只设置 一次定名 的 HttpClient,并多次重用它调用一个特定 API 提供者的全部 API。
  3. 我们可以根据这些客户端在应用程序不同地区 的利用 环境 ,设置 多个不同设置 的定名 HttpClient 对象。

我们可以在 Startup.cs 文件的 ConfigureServices 方法中,利用 前面用过的名为 AddHttpClient 方法指定一个定名 的 HttpClient。

Startup.cs

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddRazorPages();
  4. services.AddServerSideBlazor();
  5. services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
  6. services.AddHttpClient("HolidaysApi", c =>
  7. {
  8. c.BaseAddress = new Uri("https://date.nager.at/");
  9. c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
  10. });
  11. }
复制代码

我们必要 指定客户端的名称(比方 HolidaysApi),我们还可以设置 如上所示的 BaseAddressDefaultRequestHeaders 和其他属性。

设置 了定名 HttpClient 之后,我们可以利用 类似 的 CreateClient 方法在整个应用程序中创建 HttpClient 对象,不过这次我们必要 指定想要创建哪个已定名 的客户端(比方 HolidaysApi)。

HolidaysApiService.cs

  1. public class HolidaysApiService : IHolidaysApiService
  2. {
  3. private readonly IHttpClientFactory _clientFactory;
  4. public HolidaysApiService(IHttpClientFactory clientFactory)
  5. {
  6. _clientFactory = clientFactory;
  7. }
  8. public async Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest)
  9. {
  10. var result = new List<HolidayResponseModel>();
  11. var url = string.Format("api/v2/PublicHolidays/{0}/{1}",
  12. holidaysRequest.Year, holidaysRequest.CountryCode);
  13. var request = new HttpRequestMessage(HttpMethod.Get, url);
  14. var client = _clientFactory.CreateClient("HolidaysApi");
  15. var response = await client.SendAsync(request);
  16. if (response.IsSuccessStatusCode)
  17. {
  18. var stringResponse = await response.Content.ReadAsStringAsync();
  19. result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse,
  20. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  21. }
  22. else
  23. {
  24. result = Array.Empty<HolidayResponseModel>().ToList();
  25. }
  26. return result;
  27. }
  28. }
复制代码

我们在 CreateClient 方法中传递的名称(比如 HolidaysApi)必须与我们在 Startup.cs 文件中设置 的名称同等 。每次调用 CreateClient 方法时,都会为我们创建一个新的 HttpClient 实例。

别的 ,我们不必要 在哀求 的 URL 中指定 API 主机名称,由于 我们在 Startup.cs 文件中已经指定过基地址了。

再次运行应用程序并提供国家代码和年份值,您应该能看到以下公共假期列表。

 

Blazor Server 应用程序中举行
 HTTP 哀求

五、在 Blazor Server 应用程序中创建范例 化 HttpClient 对象

创建和利用 HttpClient 对象的第三种选择是利用 范例 化客户端。这种客户端具有以下好处:

  1. 它们提供与定名 客户端同样的功能,但无需利用 字符串作为键。
  2. 它们在利用 客户端时提供智能感知和编译器帮助。
  3. 它们提供了一个单一的存储单元来设置 特定的 HttpClient 并与之交互。比方 ,我们可以设置 针对 Facebook API 的一个特定终端的一个范例 化 HttpClient,而且该 HttpClient 可以封装利用 该特定终端所需的全部 逻辑。
  4. 它们与依靠 注入 (DI) 一起利用 ,可以在必要 的地方注入。

要设置 范例 化的 HTTPClient,我们必要 在 Startup.cs 文件中利用 类似 的 AddHttpClient 方法注册它,但这一次,我们必要 传递我们的服务名称 HolidaysApiService 作为它的范例 。

Startup.cs

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddRazorPages();
  4. services.AddServerSideBlazor();
  5. services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
  6. services.AddHttpClient<HolidaysApiService>();
  7. }
复制代码

在上面的代码片断 中,HTTP 客户端和我们的服务 HolidaysApiService 都将注册为瞬时客户端和服务。这将答应 我们在服务的构造函数中传递 HttpClient,如以下代码片断 所示。请留意 ,HttpClient 是怎样 公开为服务的 public 属性的。

HolidaysApiService.cs

  1. public class HolidaysApiService : IHolidaysApiService
  2. {
  3. public HttpClient Client { get; }
  4. public HolidaysApiService(HttpClient client)
  5. {
  6. client.BaseAddress = new Uri("https://date.nager.at/");
  7. client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
  8. Client = client;
  9. }
  10. public async Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest)
  11. {
  12. var result = new List<HolidayResponseModel>();
  13. var url = string.Format("api/v2/PublicHolidays/{0}/{1}",
  14. holidaysRequest.Year, holidaysRequest.CountryCode);
  15. var response = await Client.GetAsync(url);
  16. if (response.IsSuccessStatusCode)
  17. {
  18. var stringResponse = await response.Content.ReadAsStringAsync();
  19. result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse,
  20. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  21. }
  22. else
  23. {
  24. result = Array.Empty<HolidayResponseModel>().ToList();
  25. }
  26. return result;
  27. }
  28. }
复制代码

范例 化客户端的设置 也可以不在范例 化客户端的构造函数中指定,而在注册期间在 Startup.cs 文件的 ConfigureServices 方法中指定。

Startup.cs

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddRazorPages();
  4. services.AddServerSideBlazor();
  5. services.AddHttpClient<IHolidaysApiService, HolidaysApiService>(c =>
  6. {
  7. c.BaseAddress = new Uri("https://date.nager.at/");
  8. c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
  9. });
  10. }
复制代码

假如 您利用 的是这种方式,则无需单独注册您的服务。您可以从 ConfigureServices 方法中删除下面这行代码。

  1. services.AddSingleton<IHolidaysApiService, HolidaysApiService>();
复制代码

可以将 HttpClient 对象密封在一个范例 化客户端中,而不公开为 public 属性。然后,我们可以在服务内部的恣意 方法中利用 这个客户端。

  1. public class HolidaysApiService : IHolidaysApiService
  2. {
  3. private readonly HttpClient _httpClient;
  4. public HolidaysApiService(HttpClient client)
  5. {
  6. _httpClient = client;
  7. }
  8. public async Task<List<HolidayResponseModel>> GetHolidays(HolidayRequestModel holidaysRequest)
  9. {
  10. var result = new List<HolidayResponseModel>();
  11. var url = string.Format("api/v2/PublicHolidays/{0}/{1}",
  12. holidaysRequest.Year, holidaysRequest.CountryCode);
  13. var response = await _httpClient.GetAsync(url);
  14. if (response.IsSuccessStatusCode)
  15. {
  16. var stringResponse = await response.Content.ReadAsStringAsync();
  17. result = JsonSerializer.Deserialize<List<HolidayResponseModel>>(stringResponse,
  18. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  19. }
  20. else
  21. {
  22. result = Array.Empty<HolidayResponseModel>().ToList();
  23. }
  24. return result;
  25. }
  26. }
复制代码

再次运行应用程序,并提供国家代码和年份值,您应该可以或许 看到以下公共假期列表。

 

Blazor Server 应用程序中举行
 HTTP 哀求

到此这篇关于Blazor Server 应用程序中举行 HTTP 哀求 的文章就先容 到这了,更多相干 Blazor Server内容请搜刮 脚本之家从前 的文章或继续欣赏 下面的相干 文章盼望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar 安桐AnnTong | 2021-9-20 00:21:10 | 显示全部楼层
东方不败还是灭绝师太啊?
回复

使用道具 举报

avatar 不好吃荤漳 | 2021-9-26 16:52:42 | 显示全部楼层
顶!顶!顶!
回复

使用道具 举报

avatar 坏坏的猪蹄肇 | 2021-9-30 08:32:50 | 显示全部楼层
admin楼主说的我也略懂!
回复

使用道具 举报

avatar 雍不言弃 | 2021-9-30 08:32:54 | 显示全部楼层
被admin楼主的逻辑打败了!
回复

使用道具 举报

avatar 小野妹子868 | 2021-10-1 22:20:21 | 显示全部楼层
感觉不错!
回复

使用道具 举报

avatar 困虫斗倜 | 2021-10-2 11:49:28 | 显示全部楼层
admin楼主,我告诉你一个你不知道的的秘密,有一个牛逼的网站,影视频道的网站所有电影和连续剧都可以免费看的。访问地址:http://tv.mxswl.com
回复

使用道具 举报

avatar NYB冬冬 | 2021-10-2 11:49:30 | 显示全部楼层
admin楼主,我告诉你一个你不知道的的秘密,有一个牛逼的网站,影视频道的网站所有电影和连续剧都可以免费看的。访问地址:http://tv.mxswl.com
回复

使用道具 举报

avatar 狂人阿飙湛 | 2021-10-3 01:15:01 | 显示全部楼层
内容很有深度!
回复

使用道具 举报

avatar 擎宇温 | 2021-10-3 05:35:47 | 显示全部楼层
经典,收藏了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则