5.41自定义 HTTP 声明提取器

创建于 2026 年 8 月 17 日约 9 分钟读完

5.1 声明式请求 章节中,我们了解到每种特性或参数类型都对应着一种 HTTP 声明式提取器。以下系统预置的特性提取器及其对应的实现:

通过自定义 HTTP 声明式提取器,您可以为 HTTP 声明式接口提供额外的功能。以下是一个自定义 AcceptAttribute 特性及其提取器的示例:

1. 定义 AcceptAttribute 特性

设置 AcceptAttribute 特性作用范围为方法或接口上。

cs
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Interface)]public sealed class AcceptAttribute : Attribute{    public AcceptAttribute(string accept)    {        ArgumentException.ThrowIfNullOrWhiteSpace(accept);        Accept = accept;    }    public string Accept { get; set; }}

2. 实现 AcceptDeclarativeExtractor 提取器

解析 AcceptAttribute 特性并设置给 HttpRequestBuilder 实例。

cs
public sealed class AcceptDeclarativeExtractor : IHttpDeclarativeExtractor{    // 实现 Extract 方法    public void Extract(HttpRequestBuilder httpRequestBuilder, HttpDeclarativeParsingContext context)    {        // 获取方法或接口定义的 AcceptAttribute 特性        if (!context.IsMethodDefined<AcceptAttribute>(out var acceptAttribute, true))        {            return;        }        // 设置 Accept 头        httpRequestBuilder.WithHeader("Accept", acceptAttribute.Accept, replace: true);    }}

提取器 Extract 方法的 context 参数的类型为 HttpDeclarativeParsingContext,包含以下属性和方法:

  • 属性

    • Method:被调用方法(MethodInfo 类型)。
    • Args:被调用方法的参数值数组(object[] 类型)。
    • MethodMetadata:被调用方法的元数据(HttpDeclarativeMethodMetadata 类型)。
    • Parameters:被调用方法的参数键值字典(IReadOnlyDictionary<ParameterInfo, object?> 类型)。
    • UnFrozenParameters:被调用方法的非冻结类型参数键值字典(IReadOnlyDictionary<ParameterInfo, object?> 类型)。
  • 方法

    • IsFrozenParameter(parameter):判断参数是否是冻结参数类型。
    • IsMethodDefined<TAttribute>(out var attribute, inherit):检查被调用方法是否定义了指定特性。
    • GetMethodDefinedCustomAttributes(inherit, methodScanFirst):获取被调用方法指定特性的所有实例。

3. 在配置中注册自定义提取器

Startup.csProgram.cs 文件中,配置并注册 HttpRemote 服务,以启用自定义 HTTP 声明式提取器功能。

cs
services.AddHttpRemote(builder =>{    builder.AddHttpDeclarativeExtractors(() => [ new AcceptDeclarativeExtractor() ]);});

4. 在 HTTP 声明式接口中使用自定义特性

cs
[Accept("text/html")]public interface IHttpService : IHttpDeclarative{    // 在方法上应用    [Accept("text/xml")]    [Get("https://furion.net/")]    Task<string> GetStringAsync();}

通过上述步骤,您已经成功创建了一个自定义的 HTTP 声明式提取器。这不仅可以增强 HTTP 声明式接口的功能,还可以使代码更加简洁和易于维护。您可以根据自己的需求继续扩展和自定义其他 HTTP 声明式提取器。

如需更多自定义的 HTTP 声明式提取器,请参考框架内置的 HTTP 声明式提取器代码实现。