You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Blazor项目多差异化配置REST API客户端实现方案问询

多差异化配置REST API调用的Blazor实现方案

核心实现采用命名式HttpClient + 策略模式的组合方案,完全适配.NET官方推荐的IHttpClientFactory最佳实践,既实现了多客户端配置的完全隔离,又满足了可扩展、易维护的要求。

第一步:注册差异化命名HttpClient

在Program.cs(.NET 6+,Startup.cs逻辑一致)中为每个不同配置的API注册独立命名的HttpClient,避免全局配置污染:

var builder = WebApplication.CreateBuilder(args);

// 注册自定义JWT处理程序,后续给授权客户端用
builder.Services.AddTransient<JwtAuthHandler>();

// 1. 注册需要跳过证书校验的API客户端
builder.Services.AddHttpClient("InsecureApiClient", client =>
{
    client.BaseAddress = new Uri("https://your-insecure-api-address.com/");
    client.Timeout = TimeSpan.FromSeconds(30);
})
.ConfigurePrimaryHttpMessageHandler(() => 
{
    return new HttpClientHandler
    {
        // 仅该客户端跳过证书校验,不会影响其他HTTP请求
        ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
    };
});

// 2. 注册支持带请求体GET的API客户端
builder.Services.AddHttpClient("CustomGetApiClient", client =>
{
    client.BaseAddress = new Uri("https://custom-get-api-address.com/");
});

// 3. 注册需要携带JWT认证的API客户端
builder.Services.AddHttpClient("JwtAuthApiClient", client =>
{
    client.BaseAddress = new Uri("https://jwt-protected-api-address.com/");
})
.AddHttpMessageHandler<JwtAuthHandler>();

注意:跳过证书校验存在安全风险,仅建议在内部测试环境或者完全可控的私有网络场景下使用,生产环境请配置合法的SSL证书。

JWT自动注入的消息处理程序示例:

public class JwtAuthHandler : DelegatingHandler
{
    private readonly IAuthService _authService; // 你自己实现的认证服务,用于获取当前用户的JWT
    public JwtAuthHandler(IAuthService authService)
    {
        _authService = authService;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var token = await _authService.GetCurrentUserTokenAsync();
        if (!string.IsNullOrEmpty(token))
        {
            request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
        }
        return await base.SendAsync(request, cancellationToken);
    }
}

第二步:用策略模式封装API调用逻辑

定义统一的调用策略接口,每个API对应一个独立的策略实现,内部绑定对应命名的HttpClient:

定义公共策略接口

public interface IApiClientStrategy
{
    Task<TResponse> SendAsync<TResponse>(string path, HttpMethod method, object payload = null, CancellationToken cancellationToken = default);
}

各API独立策略实现

  • 跳过证书校验的API策略:
public class InsecureApiClientStrategy : IApiClientStrategy
{
    private readonly HttpClient _httpClient;
    public InsecureApiClientStrategy(IHttpClientFactory httpClientFactory)
    {
        _httpClient = httpClientFactory.CreateClient("InsecureApiClient");
    }

    public async Task<TResponse> SendAsync<TResponse>(string path, HttpMethod method, object payload = null, CancellationToken cancellationToken = default)
    {
        using var request = new HttpRequestMessage(method, path);
        if (payload != null) request.Content = JsonContent.Create(payload);
        using var response = await _httpClient.SendAsync(request, cancellationToken);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<TResponse>(cancellationToken: cancellationToken);
    }
}
  • 带请求体GET的API策略:
public class CustomGetApiClientStrategy : IApiClientStrategy
{
    private readonly HttpClient _httpClient;
    public CustomGetApiClientStrategy(IHttpClientFactory httpClientFactory)
    {
        _httpClient = httpClientFactory.CreateClient("CustomGetApiClient");
    }

    public async Task<TResponse> SendAsync<TResponse>(string path, HttpMethod method, object payload = null, CancellationToken cancellationToken = default)
    {
        using var request = new HttpRequestMessage(method, path);
        // 特殊处理带请求体的GET请求
        if (payload != null) request.Content = JsonContent.Create(payload);
        using var response = await _httpClient.SendAsync(request, cancellationToken);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<TResponse>(cancellationToken: cancellationToken);
    }
}
  • JWT认证的API策略:
public class JwtAuthApiClientStrategy : IApiClientStrategy
{
    private readonly HttpClient _httpClient;
    public JwtAuthApiClientStrategy(IHttpClientFactory httpClientFactory)
    {
        _httpClient = httpClientFactory.CreateClient("JwtAuthApiClient");
    }

    public async Task<TResponse> SendAsync<TResponse>(string path, HttpMethod method, object payload = null, CancellationToken cancellationToken = default)
    {
        using var request = new HttpRequestMessage(method, path);
        if (payload != null) request.Content = JsonContent.Create(payload);
        using var response = await _httpClient.SendAsync(request, cancellationToken);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<TResponse>(cancellationToken: cancellationToken);
    }
}

第三步:注册策略并实现上下文调用

将所有策略和调用上下文注册到DI容器,实现按需获取:

// 注册所有策略
builder.Services.AddSingleton<IApiClientStrategy, InsecureApiClientStrategy>();
builder.Services.AddSingleton<IApiClientStrategy, CustomGetApiClientStrategy>();
builder.Services.AddSingleton<IApiClientStrategy, JwtAuthApiClientStrategy>();

// 注册策略上下文,方便快速获取对应策略
public class ApiClientContext
{
    private readonly IEnumerable<IApiClientStrategy> _strategies;
    public ApiClientContext(IEnumerable<IApiClientStrategy> strategies)
    {
        _strategies = strategies;
    }

    public IApiClientStrategy GetStrategy<TStrategy>() where TStrategy : IApiClientStrategy
    {
        return _strategies.OfType<TStrategy>().First();
    }
}

builder.Services.AddSingleton<ApiClientContext>();

第四步:Blazor组件中使用

直接注入上下文按需调用即可:

@inject ApiClientContext ApiContext

@code {
    // 调用跳过证书的API
    private async Task CallInsecureApi()
    {
        var client = ApiContext.GetStrategy<InsecureApiClientStrategy>();
        var result = await client.SendAsync<DataModel>("api/data", HttpMethod.Get);
    }

    // 调用带请求体的GET接口
    private async Task CallCustomGetApi()
    {
        var client = ApiContext.GetStrategy<CustomGetApiClientStrategy>();
        var queryPayload = new { Page = 1, PageSize = 20, Keyword = "test" };
        var result = await client.SendAsync<PageResult>("api/list", HttpMethod.Get, queryPayload);
    }

    // 调用JWT授权的API
    private async Task CallJwtAuthApi()
    {
        var client = ApiContext.GetStrategy<JwtAuthApiClientStrategy>();
        var result = await client.SendAsync<UserInfo>("api/user/info", HttpMethod.Get);
    }
}

方案优势

  • 所有HttpClient配置完全隔离,修改单个API的配置不会影响其他请求,无全局配置污染
  • 策略模式符合开闭原则,后续新增API仅需要添加新的策略实现即可,无需修改原有逻辑
  • 基于IHttpClientFactory实现,自动管理HttpClient生命周期,规避端口耗尽、DNS更新不生效等常见问题
  • 所有调用逻辑可单独单元测试,无硬编码耦合

内容的提问来源于stack exchange,提问作者Randy Marsh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:54:03