5.12基地址 / 来源 / 版本 / 异常抑制

当需要对接多个第三方 API 时,我们通常会全局注册并配置多个 HttpClient 实例的 BaseAddress。例如:

设置请求基地址#

当需要对接多个第三方 API 时,我们通常会全局注册并配置多个 HttpClient 实例的 BaseAddress。例如:

cs
// 配置默认客户端的基地址services.AddHttpClient(string.Empty, client =>{    client.BaseAddress = new Uri("https://furion.net/");});// 配置GitHub客户端的基地址services.AddHttpClient("github", client =>{    client.BaseAddress = new Uri("https://github.com/");});

随后可通过 [HttpClientName(客户端名称)] 特性指定要使用的客户端。

除了全局配置,框架还支持在声明式请求中局部设置基地址,允许在构建请求时动态指定。

HTTP 声明式请求通过 BaseAddressAttribute 特性来设置请求基地址。相应的 HTTP 声明式提取器实现为 BaseAddressDeclarativeExtractor 类型,该类型负责解析 BaseAddressAttribute 特性并构建 HttpRequestBuilder 实例所需的请求基地址配置。

cs
// 在接口定义上应用,影响所有方法[BaseAddress("https://furion.net")]public interface IHttpService : IHttpDeclarative{    [Get("/api/test")]    Task<string> GetStringAsync();    // 在方法上应用    [BaseAddress("https://baiqian.com")]    [Get("/api/test/2")]    Task<string> GetStringAsync();    // 可充当前缀使用    [BaseAddress("/furion")]    [Get("/api/test/2")]    Task<string> GetStringAsync();}

启用后,发送 HTTP 远程请求时会自动设置请求基地址。

处理逻辑说明

  • 若请求地址为绝对地址,则直接使用该地址发送请求。
  • 若请求地址为相对地址:
    • 未设置局部 BaseAddress 时,将其与全局 HttpClient 实例的 BaseAddress 拼接,作为最终请求地址。
    • 已设置局部 BaseAddress 时:
      • 若局部 BaseAddress 为相对地址,则先将局部 BaseAddress 拼接到请求地址前,再与全局 BaseAddress 拼接。
      • 若局部 BaseAddress 为绝对地址,则直接将该绝对地址与请求地址拼接,作为最终请求地址(此时忽略全局 BaseAddress)。

BaseAddressAttribute 包含以下构造函数和属性:

  • 构造函数

    • new(baseAddress):作用于方法或接口,设置请求基地址。
  • 属性

    • BaseAddress:请求基地址(string 类型)。

设置来源地址(防盗链)#

当访问某些第三方服务器时,服务器可能会验证请求头中的 Referer 来源地址。例如在下载图片时,可能因触发防盗链机制导致获取的图片不符合预期。此时,可通过设置 Referer 请求头,模拟来源页面以绕过防盗链检测。

HTTP 声明式请求通过 RefererAttribute 特性来设置请求来源地址。相应的 HTTP 声明式提取器实现为 RefererDeclarativeExtractor 类型,该类型负责解析 RefererAttribute 特性并构建 HttpRequestBuilder 实例所需的请求来源地址配置。

cs
// 在接口定义上应用,影响所有方法[Referer("https://furion.net")]public interface IHttpService : IHttpDeclarative{    [Get("https://furion.net/logo.png")]    Task<string> GetStringAsync();    // 在方法上应用    [Referer("https://baiqian.com")]    [Get("https://furion.net/logo2.png")]    Task<string> GetStringAsync();}

启用后,发送 HTTP 远程请求时会自动设置请求来源地址。

为简化配置,框架提供了内置模板字符串 "{BASE_ADDRESS}",可自动提取请求地址的基地址作为 Referer

cs
[Referer("{BASE_ADDRESS}")] // 发送时自动替换 {BASE_ADDRESS} 为 https://furion.net/public interface IHttpService : IHttpDeclarative{    [Get("https://furion.net/logo.png")]    Task<string> GetStringAsync();}

RefererAttribute 包含以下构造函数和属性:

  • 构造函数

    • new(referer):作用于方法或接口,设置请求来源地址。
  • 属性

    • Referer:请求来源地址(string 类型)。

配置 HTTP 版本#

在发起 HTTP 远程请求时,默认采用的 HTTP 协议版本为 1.1。不过,在访问部分第三方服务器时,这些服务器可能会对 HTTP 版本进行校验(例如,要求使用 2.0 版本)。

HTTP 声明式请求通过 HttpVersionAttribute 特性来设置请求来源地址。相应的 HTTP 声明式提取器实现为 HttpVersionDeclarativeExtractor 类型,该类型负责解析 HttpVersionAttribute 特性并构建 HttpRequestBuilder 实例所需的 HTTP 版本配置。

cs
// 在接口定义上应用,影响所有方法[HttpVersion("1.2")]public interface IHttpService : IHttpDeclarative{    [Get("https://furion.net/logo.png")]    Task<string> GetStringAsync();    // 在方法上应用    [HttpVersion("2.0")]    [Get("https://furion.net/logo2.png")]    Task<string> GetStringAsync();}

启用后,发送 HTTP 远程请求时会自动设置 HTTP 版本。

除可通过 [HttpVersion] 特性进行配置外,系统还支持全局设置方式,具体示例如下:

cs
// 配置默认客户端services.AddHttpClient(string.Empty, client =>{    client.DefaultRequestVersion = HttpVersion.Version10;});// 配置特定客户端services.AddHttpClient("weixin", client =>{    client.DefaultRequestVersion = HttpVersion.Version10;});

HttpVersionAttribute 包含以下构造函数和属性:

  • 构造函数

    • new(version):作用于方法或接口,设置 HTTP 版本。
  • 属性

    • VersionHTTP 版本(string 类型)。

异常抑制机制(静默处理)#

在发起 HTTP 远程请求时,可能会遇到以下异常情况:

  • 目标主机不可达
  • 请求被取消
  • 请求超时
  • 其他网络异常

默认情况下,这些异常会中断程序执行。虽然开发者通常使用 try/catch 进行异常处理,但在某些场景下,我们更希望异常发生时静默返回 null 而不中断流程。为此,框架提供了灵活的异常抑制功能。

HTTP 声明式请求通过 SuppressExceptionsAttribute 特性来设置请求来源地址。相应的 HTTP 声明式提取器实现为 SuppressExceptionsDeclarativeExtractor 类型,该类型负责解析 SuppressExceptionsAttribute 特性并构建 HttpRequestBuilder 实例所需异常抑制配置。

cs
// 在接口定义上应用,影响所有方法[SuppressExceptions] // 抑制所有异常public interface IHttpService : IHttpDeclarative{    [Get("https://furion.net/logo.png")]    Task<string> GetStringAsync();    // 在方法上应用    [SuppressExceptions(typeof(TimeoutException), typeof(TaskCanceledException))]    // 抑制超时和取消异常    [Get("https://furion.net/logo2.png")]    Task<string> GetStringAsync();    [SuppressExceptions(false)]    // 禁用抑制异常(恢复缺省配置)    [Get("https://furion.net/logo2.png")]    Task<string> GetStringAsync();}

启用后,发送 HTTP 远程请求时会自动设置异常抑制机制。

SuppressExceptionsAttribute 包含以下构造函数和属性:

  • 构造函数

    • new():作用于方法或接口,抑制所有异常。
    • new(enable):作用于方法或接口,是否启用异常抑制机制。
    • new(types):作用于方法或接口,抑制指定类型异常。
  • 属性

    • Types:异常抑制类型集合(type[] 类型,数组中的每个元素必须是 System.Exception 类型或其派生类型)。