5.41Custom HTTP Declarative Extractor

Updated on Aug 20, 2026~14 min read

In the 5.1 Declarative Requests section, we learned that every attribute or parameter type corresponds to an HTTP declarative extractor. The following are the system-provided attribute extractors and their corresponding implementations:

By customizing an HTTP declarative extractor, you can provide additional functionality for HTTP declarative interfaces. The following is an example of a custom AcceptAttribute attribute and its extractor:

1. Defining the AcceptAttribute attribute

Set the AcceptAttribute attribute's scope to methods or interfaces.

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. Implementing the AcceptDeclarativeExtractor extractor

Parse the AcceptAttribute attribute and set it on the HttpRequestBuilder instance.

cs
public sealed class AcceptDeclarativeExtractor : IHttpDeclarativeExtractor{    // Implement the Extract method    public void Extract(HttpRequestBuilder httpRequestBuilder, HttpDeclarativeParsingContext context)    {        // Get the AcceptAttribute attribute defined on the method or interface        if (!context.IsMethodDefined<AcceptAttribute>(out var acceptAttribute, true))        {            return;        }        // Set the Accept header        httpRequestBuilder.WithHeader("Accept", acceptAttribute.Accept, replace: true);    }}

The context parameter of the extractor's Extract method is of type HttpDeclarativeParsingContext, which contains the following properties and methods:

  • Properties:

    • Method: The invoked method (of type MethodInfo).
    • Args: The array of argument values of the invoked method (of type object[]).
    • MethodMetadata: The metadata of the invoked method (of type HttpDeclarativeMethodMetadata).
    • Parameters: The dictionary of parameter keys and values of the invoked method (of type IReadOnlyDictionary<ParameterInfo, object?>).
    • UnFrozenParameters: The dictionary of non-frozen typed parameter keys and values of the invoked method (of type IReadOnlyDictionary<ParameterInfo, object?>).
  • Methods:

    • IsFrozenParameter(parameter): Determines whether a parameter is a frozen parameter type.
    • IsMethodDefined<TAttribute>(out var attribute, inherit): Checks whether the invoked method defines the specified attribute.
    • GetMethodDefinedCustomAttributes(inherit, methodScanFirst): Gets all instances of the specified attribute defined on the invoked method.

3. Registering the custom extractor in configuration

In the Startup.cs or Program.cs file, configure and register the HttpRemote service to enable the custom HTTP declarative extractor functionality.

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

4. Using the custom attribute in an HTTP declarative interface

cs
[Accept("text/html")]public interface IHttpService : IHttpDeclarative{    // Apply on the method    [Accept("text/xml")]    [Get("https://furion.net/")]    Task<string> GetStringAsync();}

Through the steps above, you have successfully created a custom HTTP declarative extractor. This not only enhances the functionality of HTTP declarative interfaces but also makes the code more concise and easier to maintain. You can continue to extend and customize other HTTP declarative extractors according to your needs.

For more custom HTTP declarative extractors, refer to the framework's built-in HTTP declarative extractor code implementations.