blazor调用webapi接口

发布时间 2023-12-14 10:59:15作者: [在河之洲]

Blazor页面

  1. 页面调用webapi接口不再使用HttpClient,改用IHttpClientFactory

  2. 引用 Microsoft.Extensions.Http

    IHttpClientFactory
    利用IHttpClientFactory可以无缝创建HttpClient实例,避免手动管理它们的生命周期。

    当使用ASP.Net Core开发应用程序时,可能经常需要通过HttpClient调用WebAPI的方法以检查终结点是否正常工作。要实现这一点,通常需要实例化HttpClient并使用该实例来调用你的方法。但是直接使用HttpClient也有一些缺点,主要与手动管理实例的生命周期有关。

    你可以使用IHttpClientFactory创建HttpClient来避免这些问题。IHttpClientFactory是在.Net Core 2.1引入的,它提供了一个命名,配置和创建HttpClient实例的核心功能,并能自动管理实例的池化和生命周期。

    为什么使用IHttpClientFactory?
    尽管HttpClient没有直接实现IDisposable接口,但它扩展了System.Net.Http。HttpMessageInvoker,这个类实现了IDisposable。然而,当使用HttpClient实例时,你不应该手动操作释放它们。尽管可以在HttpClient实例上调用Dispose方法,但不推荐这样做。
    应该怎么做呢?一种选择是使HttpClient静态化,或者将HttpClient的非静态实例包装在自定义类中,并使其成为单例类。但是更好的替代方法是使用IHttpClientFactory来生成HttpClient的实例,然后使用该实例来调用操作方法。

    当你释放HttpClient实例时,连接将保持打开状态长达4分钟。此外,可以在任何时间点打开socket的数量是有限制的——不能同时打开太多socket。因此,当使用太多HttpClient实例时,可能会耗尽socket。
    这就是IHttpClientFactory的意义所在。你可以通过利用IHttpClientFactory来创建用于调用HTTP API方法的HttpClient实例,以避免HttpClient所面临的问题。在ASP.NET Core中实现IHttpClientFactory的主要目标是为了确保使用工厂模式创建HttpClient实例的同时避免socket耗尽。

  3. 代码示例

    @using System.Text.Json
    @using System.Text.Json.Serialization
    @inject IHttpClientFactory ClientFactory

    <h1>Call web API from a Blazor Server Razor component</h1>
    @code {

    	protected override async Task OnInitializedAsync()
    	{
    		try
    		{
    			var request = new HttpRequestMessage(HttpMethod.Get,
    					"https://localhost:1234/api/xxxx");

    			var client = ClientFactory.CreateClient();

    			var response = await client.SendAsync(request);

    			if (response.IsSuccessStatusCode)
    			{
    				var aa = response.Content.ReadAsStringAsync().Result;
    			}
    			else
    			{
    			}
    		}
    		catch (Exception ex)
    		{
    			//TypeError: Failed to fetch. Webapi跨域问题
    			throw;
    		}
    	}

WebApi

//解决跨域访问
app.UseCors(cors => cors
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => true)
.AllowCredentials()
);