5.11Setting Query Parameters (URL Parameters)
Add, modify, or remove URL query parameters.
HTTP Declarative Requests set or remove query parameters via the QueryParamAttribute attribute. The corresponding HTTP declarative extractor is implemented as the QueryParamDeclarativeExtractor type, which is responsible for parsing the QueryParamAttribute attribute and building the query parameter configuration required by an HttpRequestBuilder instance.
1. Adding Query Parameters
Using the QueryParamAttribute attribute, you can conveniently add query parameters on an interface, method, or parameter.
// Applied on the interface definition, affecting all methods[QueryParam("query1", "value1")][QueryParam("query2", "value2")]public interface IHttpService : IHttpDeclarative{ // Applied on the method [QueryParam("query3", "value3")] [QueryParam("query4", "value4")] [Get("https://furion.net/")] Task<string> GetStringAsync(); // Applied on the parameter, supports the AliasAs property to specify an alias, and can be specified multiple times [QueryParam("query3", "value3")] [Get("https://furion.net/")] Task<string> GetStringAsync([QueryParam] string query4, [QueryParam][QueryParam(AliasAs = "query5")] int lastQuery); // On the parameter, a default value can be set via the Value property, and the same can be set for the age parameter, e.g. int? age = 30 [Get("https://furion.net/")] Task<string> GetStringAsync([QueryParam(Value = 30)] int? age); // Supports using an object as a query parameter and specifying a prefix [Get("https://furion.net/")] Task<string> GetStringAsync([QueryParam(Prefix = "user")] object obj); // Supports defining an alias via [AliasAs] [Get("https://furion.net/")] Task<string> GetStringAsync([QueryParam][AliasAs("query5")] int lastQuery); // Supports ignoring null-valued parameters; if the value of str1 is null, it is ignored [Get("https://furion.net/")] Task<string> GetStringAsync([QueryParam(IgnoreNullValues = true)] string? str1, [QueryParam] string? str2); // Supports format formatting [Get("https://furion.net/")] Task<string> GetStringAsync([QueryParam(Format = "yyyyMMdd")] DateTime date); // Frozen parameter types are ignored [Get("https://furion.net/")] Task<string> GetStringAsync([QueryParam] CancellationToken cancellationToken);}If duplicate query parameter keys exist, they are merged into multiple key-value pairs (e.g. key1=value1&key1=value2). By setting the Replace = true property, you can override the previous query parameters and the parameters from the original URL address. By default, query parameters with a null value are added to the URL; to ignore these parameters, set IgnoreNullValues = true.
2. Removing Query Parameters
In the QueryParamAttribute attribute, specifying only the query parameter key without a value means removing that parameter. This is effective when applied on an interface or method.
[QueryParam("query1", "value1")] // Add the query1 parameter[QueryParam("query2")] // Mark query2 as to be removedpublic interface IHttpService : IHttpDeclarative{ [QueryParam("query2", "value2")] // Add the query2 parameter [QueryParam("query3", "value3")] // Add the query3 parameter [QueryParam("query3")] // Mark query3 as to be removed [Get("https://furion.net/")] Task<string> GetStringAsync();}Before sending the HTTP request, the set of query parameters marked for removal specified in the configuration will be removed. In other words, the removal operation is executed after all setting operations are called.
In the example above, although the GetStringAsync method attempts to add the query2 and query3 parameters via the [QueryParam] attribute, the subsequent [QueryParam("query2")] and [QueryParam("query3")] attributes specify only the query parameter key without a value, so these two keys are removed when the request URL is finally built. Only the query1 parameter is retained in the request URL.
3. URL Parameter Formatter
When setting query parameters for an HTTP request, the framework passes the parameter keys and values to IUrlParameterFormatter for formatting. The default implementation UrlParameterFormatter generates a key=value key-value pair for each value. However, certain types (such as DateTime) may require special handling, or you may want to change the output shape of the entire key-value pair (for example, outputting multiple values as an array format like key[0]=val1&key[1]=val2); in such cases you can implement a custom formatter.
The following example shows how to override the Format method to format DateTime values as yyyyMMdd, while using the default handling for other types:
public class CustomUrlParameterFormatter : UrlParameterFormatter{ /// <inheritdoc /> public override IEnumerable<KeyValuePair<string, string?>>? Format(UrlFormattingContext context, string key, IEnumerable<object?> values) { foreach (var value in values) { if (value is DateTime dateTime) { yield return new(key, dateTime.ToString("yyyyMMdd")); // Format continue; } yield return new(key, FormatValue(context, value)); } }}After completing the custom formatter, you can register it as the default URL parameter formatter when configuring HttpRemoteOptions:
services.AddHttpRemote(builder => {}) .ConfigureOptions(options => { options.UrlParameterFormatter = new CustomUrlParameterFormatter(); });In this way, when building URL query parameters, if a DateTime value is encountered, the framework automatically formats it as a yyyyMMdd string, thereby ensuring the output meets expectations.
4. URL Parameter Sorting
Although the need to sort URL query parameters is relatively rare, in some systems with higher security requirements it is often necessary to verify the order of parameters. The framework provides sorting support for this purpose, and the sorting target is the final collection of key-value pairs:
HttpRequestBuilder.Get("https://furion.net/") .WithQueryParameters(new { name = "furion", id = 1}) .SetQueryParametersSorter(pairs => pairs.OrderBy(kv => kv.Key));Configure the query parameter sorting rule via the .SetQueryParametersSorter() method. This method receives a sequence of KeyValuePair<string, string?> and returns a new sorted sequence. When it is null, no sorting is performed (the original insertion order is preserved).
QueryParamAttribute contains the following constructors and properties:
-
Constructors:
new(): Effective when applied to a parameter, indicates adding a query parameter, with the default key being the parameter name.new(name): When applied to a method or interface, it indicates removing the specified query parameter; when applied to a parameter, it indicates adding a query parameter with the key being the value of thenameargument.new(name, value): Applies to interfaces, methods, or parameters, indicating adding a query parameter with the key being the value of thenameargument, with lower priority than theAliasAsproperty.
-
Properties:
Name: The query parameter key (stringtype), with lower priority than theAliasAsproperty.Value: The query parameter value (objecttype); when the attribute is applied to a parameter, it indicates the default value.AliasAs: The query parameter key alias (stringtype), with higher priority than theNameproperty.Prefix: The query parameter prefix (stringtype), effective only for object parameters.Replace: Whether to replace existing query parameters (booltype); the default value isfalse(append).IgnoreNullValues: Whether to ignore query parameters with a null (null) value (booltype); the default value isfalse(do not ignore).Format: The format to use (string?type), effective only whenValueimplementsIFormattable.