### Make JSON-RPC Calls with JsonRpc Extension in C# Source: https://context7.com/dotnetcore/webapiclient/llms.txt Demonstrates how to make JSON-RPC calls using the WebApiClientCore.Extensions.JsonRpc package. Includes defining the API interface with JsonRpc attributes and example usage. ```csharp using WebApiClientCore.Extensions.JsonRpc; [HttpHost("http://localhost:5000/jsonrpc")] public interface ICalculatorApi { [JsonRpcMethod("add")] ITask> AddAsync( [JsonRpcParam] int a, [JsonRpcParam] int b, CancellationToken token = default); [JsonRpcMethod("subtract")] ITask> SubtractAsync( [JsonRpcParam] int a, [JsonRpcParam] int b); } // Usage var result = await calculatorApi.AddAsync(10, 5); Console.WriteLine(result.Result); // 15 // Request payload: {"jsonrpc":"2.0","method":"add","params":[10,5],"id":1} ``` -------------------------------- ### Generate WebApiClient Code from OpenAPI Specs using CLI Source: https://context7.com/dotnetcore/webapiclient/llms.txt Provides bash commands for installing and using the WebApiClientCore.OpenApi.SourceGenerator CLI tool to generate WebApiClient interface code from OpenAPI/Swagger documents. ```bash # Install the tool globally dotnet tool install WebApiClientCore.OpenApi.SourceGenerator -g # Generate code from remote Swagger JSON WebApiClientCore.OpenApi.SourceGenerator -o https://petstore.swagger.io/v2/swagger.json # Generate code with custom namespace WebApiClientCore.OpenApi.SourceGenerator -o https://api.example.com/swagger.json -n MyApp.ApiClients # Generate code from local file WebApiClientCore.OpenApi.SourceGenerator -o ./swagger.json -n MyApp.ApiClients ``` -------------------------------- ### Applying Custom Protobuf Attributes to API Interface Source: https://context7.com/dotnetcore/webapiclient/llms.txt Apply the custom Protobuf attributes to an API interface definition. This example shows how to use ProtobufReturnAttribute for the entire interface and ProtobufContentAttribute for a specific method parameter. ```csharp // Apply custom attributes [ProtobufReturn] public interface IProtobufApi { [HttpPut("/users/{id}")] Task UpdateAsync([Required, PathQuery] string id, [ProtobufContent] User user); } ``` -------------------------------- ### Implement Logging Filter Source: https://context7.com/dotnetcore/webapiclient/llms.txt Enable request and response logging using the LoggingFilter attribute at the interface or method level. Includes an example of a custom logging implementation. ```csharp [LoggingFilter] // All methods log requests public interface IUserApi { [HttpGet("api/users/{id}")] Task GetAsync(string id); [LoggingFilter(Enable = false)] // Disable logging for this method [HttpPost("api/users")] Task PostAsync([JsonContent] User user); } ``` ```csharp // Custom logging implementation public class CustomLoggingAttribute : LoggingFilterAttribute { protected override Task WriteLogAsync(ApiResponseContext context, LogMessage logMessage) { // Output logMessage to your logging destination Console.WriteLine($"Request: {logMessage.RequestTime}"); Console.WriteLine($"Response: {logMessage.ResponseTime}"); return Task.CompletedTask; } } [CustomLogging] public interface IUserApi { // Methods use custom logging } ``` -------------------------------- ### Configure Dynamic Request Hosts in C# Source: https://context7.com/dotnetcore/webapiclient/llms.txt Demonstrates how to configure dynamic request hosts using Uri parameters or custom HttpHostBaseAttribute implementations. This is useful when the host address is not known at compile time. ```csharp // Dynamic URI from parameter public interface IUserApi { [HttpGet] ITask GetAsync([Uri] string urlString, [PathQuery] string id); } // Usage var user = await userApi.GetAsync("http://api.example.com/api/users", id: "001"); ``` ```csharp // Custom host resolver public class ServiceNameHostAttribute : HttpHostBaseAttribute { public string ServiceName { get; } public ServiceNameHostAttribute(string serviceName) { ServiceName = serviceName; } public override Task OnRequestAsync(ApiRequestContext context) { var hostProvider = context.HttpContext.ServiceProvider.GetRequiredService(); string host = hostProvider.ResolveHost(ServiceName); context.HttpContext.RequestMessage.RequestUri = new Uri(host); return Task.CompletedTask; } } [ServiceNameHost("user-service")] public interface IUserApi { [HttpGet("api/users/{id}")] Task GetAsync(string id); } ``` -------------------------------- ### Path and Query Parameters Source: https://context7.com/dotnetcore/webapiclient/llms.txt Demonstrates how to define and use path and query parameters using the PathQuery attribute, including collection formats and parameter aliasing. ```APIDOC ## Path and Query Parameters Use PathQuery attribute for URL path parameters and query strings. Parameters without explicit attributes default to PathQuery behavior. ```csharp public interface IUserApi { // Path parameter (implicit PathQuery) [HttpGet("api/users/{id}")] Task GetAsync(string id); // Explicit PathQuery [HttpGet("api/users/{id}")] Task GetAsync([PathQuery] string id); // Query parameters [HttpGet("api/users")] Task SearchAsync([PathQuery] string name, [PathQuery] int? age, [PathQuery] int page = 1); // Collection formats for arrays [HttpGet("api/users")] Task GetByIdsAsync([PathQuery(CollectionFormat = CollectionFormat.Multi)] string[] ids); // Result: ?ids=001&ids=002&ids=003 [HttpGet("api/users")] Task GetByIdsCsvAsync([PathQuery(CollectionFormat = CollectionFormat.Csv)] string[] ids); // Result: ?ids=001,002,003 // Parameter alias for invalid C# identifiers [HttpGet("api/users")] Task SearchAsync([AliasAs("field-name")] string fieldName); } ``` ``` -------------------------------- ### Configure HTTP Proxy Settings in C# Source: https://context7.com/dotnetcore/webapiclient/llms.txt Shows how to configure HTTP proxy settings for WebApiClient using ConfigurePrimaryHttpMessageHandler. This is necessary when requests need to go through a proxy server. ```csharp services.AddHttpApi().ConfigureHttpApi(o => { o.HttpHost = new Uri("http://localhost:5000/"); }) .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { UseProxy = true, Proxy = new WebProxy { Address = new Uri("http://proxy.example.com:8080"), Credentials = new NetworkCredential { UserName = "proxyuser", Password = "proxypassword" } } }); ``` -------------------------------- ### Configure Json.NET Extension for Serialization in C# Source: https://context7.com/dotnetcore/webapiclient/llms.txt Shows how to use the Newtonsoft.Json extension for WebApiClient, allowing the use of Json.NET instead of System.Text.Json for serialization. Includes configuration of Json.NET options and attribute usage. ```csharp using WebApiClientCore.Extensions.NewtonsoftJson; using Newtonsoft.Json; // Configure Json.NET options services.AddHttpApi().ConfigureNewtonsoftJson(o => { o.JsonSerializeOptions.NullValueHandling = NullValueHandling.Ignore; o.JsonSerializeOptions.DateFormatString = "yyyy-MM-dd HH:mm:ss"; }); // Use JsonNet attributes [JsonNetReturn] public interface IUserApi { [HttpPost("/users")] Task PostAsync([JsonNetContent] User user); } ``` -------------------------------- ### Configure Client Certificates for HTTPS in C# Source: https://context7.com/dotnetcore/webapiclient/llms.txt Demonstrates how to configure client certificates for HTTPS mutual authentication. This is used for securing communication with APIs that require client-side certificate validation. ```csharp services.AddHttpApi().ConfigureHttpApi(o => { o.HttpHost = new Uri("https://secure-api.example.com/"); }) .ConfigurePrimaryHttpMessageHandler(() => { var handler = new HttpClientHandler(); var certificate = new X509Certificate2("client-cert.pfx", "password"); handler.ClientCertificates.Add(certificate); return handler; }); ``` -------------------------------- ### Request Headers Source: https://context7.com/dotnetcore/webapiclient/llms.txt Explains how to add static or dynamic headers to requests at different levels (interface, method, parameter). ```APIDOC ## GET /api/users/{id} (Constant Headers) ### Description Adds constant headers to the request. ### Method GET ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the user. ### Request Headers - **X-Api-Version**: 1.0 - **X-Client-Type**: mobile ### Response #### Success Response (200) - **User** (User) - The user object. ## GET /api/users/{id} (Dynamic Header from Parameter) ### Description Includes a dynamic authorization header from a method parameter. ### Method GET ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the user. #### Query Parameters - **token** (string) - Required - The authorization token. ### Response #### Success Response (200) - **User** (User) - The user object. ## GET /api/users/{id} (Multiple Headers from Object) ### Description Adds multiple headers to the request using a dictionary. ### Method GET ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the user. #### Request Body - **headers** (Dictionary) - Required - A dictionary containing headers. ### Request Example ```json { "Authorization": "Bearer token", "X-Request-Id": "" } ``` ### Response #### Success Response (200) - **User** (User) - The user object. ## GET /api/users/{id} (Custom Headers Class) ### Description Applies custom headers defined in a separate class. ### Method GET ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the user. #### Request Body - **headers** (CustomHeaders) - Required - An object containing custom headers. ### Response #### Success Response (200) - **User** (User) - The user object. ``` -------------------------------- ### Configure Path and Query Parameters Source: https://context7.com/dotnetcore/webapiclient/llms.txt Use the PathQuery attribute to define URL path parameters and query strings. Parameters without explicit attributes default to PathQuery behavior. Supports collection formats like Multi and Csv for arrays, and aliases for invalid C# identifiers. ```csharp public interface IUserApi { // Path parameter (implicit PathQuery) [HttpGet("api/users/{id}")] Task GetAsync(string id); // Explicit PathQuery [HttpGet("api/users/{id}")] Task GetAsync([PathQuery] string id); // Query parameters [HttpGet("api/users")] Task SearchAsync([PathQuery] string name, [PathQuery] int? age, [PathQuery] int page = 1); // Collection formats for arrays [HttpGet("api/users")] Task GetByIdsAsync([PathQuery(CollectionFormat = CollectionFormat.Multi)] string[] ids); // Result: ?ids=001&ids=002&ids=003 [HttpGet("api/users")] Task GetByIdsCsvAsync([PathQuery(CollectionFormat = CollectionFormat.Csv)] string[] ids); // Result: ?ids=001,002,003 // Parameter alias for invalid C# identifiers [HttpGet("api/users")] Task SearchAsync([AliasAs("field-name")] string fieldName); } ``` -------------------------------- ### Register and Configure WebApiClient Services Source: https://context7.com/dotnetcore/webapiclient/llms.txt Register HTTP API interfaces with the dependency injection container and configure global or specific options for serialization, logging, and host settings. ```csharp using Microsoft.Extensions.DependencyInjection; public void ConfigureServices(IServiceCollection services) { // Global default configuration for all interfaces services.AddWebApiClient().ConfigureHttpApi(o => { o.JsonSerializeOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; o.JsonDeserializeOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; o.KeyValueSerializeOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }); // Register specific interface with configuration services.AddHttpApi().ConfigureHttpApi(o => { o.UseLogging = true; o.HttpHost = new Uri("http://localhost:5000/"); o.UseParameterPropertyValidate = true; o.UseReturnValuePropertyValidate = true; }); // Configure underlying HttpClient services.AddHttpApi().ConfigureHttpClient(httpClient => { httpClient.Timeout = TimeSpan.FromMinutes(1); httpClient.DefaultRequestVersion = HttpVersion.Version20; }); } ``` -------------------------------- ### JSON Content Requests Source: https://context7.com/dotnetcore/webapiclient/llms.txt Demonstrates how to send requests with JSON bodies using the JsonContent attribute and handle raw JSON strings. ```APIDOC ## POST /api/users (JSON Body) ### Description Sends a POST request with a JSON-formatted request body. ### Method POST ### Endpoint /api/users ### Parameters #### Request Body - **user** (User) - Required - The user object to be serialized as JSON. ### Request Example ```json { "account": "john", "password": "secret" } ``` ### Response #### Success Response (200) - **User** (User) - The deserialized User object from the response. ## POST /api/users/raw (Raw JSON String) ### Description Sends a POST request with a raw JSON string as the request body. ### Method POST ### Endpoint /api/users/raw ### Parameters #### Request Body - **json** (string) - Required - The raw JSON string to send. ### Request Example ```json { "account": "john", "password": "secret" } ``` ``` -------------------------------- ### Configure Source Generation for .NET 8 AOT Publishing in C# Source: https://context7.com/dotnetcore/webapiclient/llms.txt Explains how to configure source generation for System.Text.Json to enable .NET 8 AOT publishing. This involves defining a JSON serializer context and configuring WebApiClient to use it. ```csharp using System.Text.Json.Serialization; // Define JSON serializer context with all model types [JsonSerializable(typeof(User))] [JsonSerializable(typeof(User[]))] [JsonSerializable(typeof(TokenResult))] public partial class AppJsonSerializerContext : JsonSerializerContext { } // Configure WebApiClient with source generator context Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services .AddWebApiClient() .ConfigureHttpApi(options => { options.PrependJsonSerializerContext(AppJsonSerializerContext.Default); }); services.AddHttpApi(); }) .Build() .Run(); ``` -------------------------------- ### XML Content Requests Source: https://context7.com/dotnetcore/webapiclient/llms.txt Illustrates sending XML content requests and expecting XML responses using XmlContent and XmlReturn attributes. ```APIDOC ## POST /api/users (XML Body) ### Description Sends a POST request with an XML-formatted request body. ### Method POST ### Endpoint /api/users ### Parameters #### Request Body - **user** (User) - Required - The user object to be serialized as XML. ### Request Example ```xml john secret ``` ### Response #### Success Response (200) - **User** (User) - The deserialized User object from the XML response. ## GET /api/users/{id} (Expect XML Response) ### Description Retrieves user data expected in XML format. ### Method GET ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the user to retrieve. ### Response #### Success Response (200) - **User** (User) - The deserialized User object from the XML response. ## POST /api/users/raw (Raw XML String) ### Description Sends a POST request with a raw XML string as the request body. ### Method POST ### Endpoint /api/users/raw ### Parameters #### Request Body - **xml** (string) - Required - The raw XML string to send. ### Request Example ```xml john secret ``` ``` -------------------------------- ### Request Timeout Configuration Source: https://context7.com/dotnetcore/webapiclient/llms.txt Explains how to configure request timeouts at the method level using constant values or dynamically via parameters. ```APIDOC ## Request Timeout Configure timeout at method level with constant values or at parameter level with dynamic values. ```csharp public interface IUserApi { // Constant timeout (10 seconds) [Timeout(10 * 1000)] [HttpGet("api/users/{id}")] Task GetAsync(string id); // Dynamic timeout from parameter [HttpGet("api/users/{id}")] Task GetAsync(string id, [Timeout] int timeoutMilliseconds); // Using TimeSpan parameter [HttpGet("api/users/{id}")] Task GetAsync(string id, [Timeout] TimeSpan timeout); } // Usage var user = await userApi.GetAsync("001", timeoutMilliseconds: 5000); var user2 = await userApi.GetAsync("001", timeout: TimeSpan.FromSeconds(30)); ``` ``` -------------------------------- ### Response Caching Source: https://context7.com/dotnetcore/webapiclient/llms.txt Illustrates how to enable response caching using the Cache attribute, specifying the cache duration and demonstrating custom cache provider registration. ```APIDOC ## Response Caching Use the Cache attribute to cache responses for a specified duration using the request URI as the cache key. ```csharp public interface IUserApi { // Cache for 60 seconds [Cache(60 * 1000)] [HttpGet("api/users/{id}")] Task GetAsync(string id); } // Custom cache provider registration public static IWebApiClientBuilder UseRedisResponseCacheProvider(this IWebApiClientBuilder builder) { builder.Services.AddSingleton(); return builder; } public class RedisResponseCacheProvider : IResponseCacheProvider { public string Name => nameof(RedisResponseCacheProvider); public Task GetAsync(string key) { // Retrieve from Redis throw new NotImplementedException(); } public Task SetAsync(string key, ResponseCacheEntry entry, TimeSpan expiration) { // Store in Redis throw new NotImplementedException(); } } ``` ``` -------------------------------- ### POST with XML Body Source: https://context7.com/dotnetcore/webapiclient/llms.txt Use the XmlContent attribute to serialize parameters as XML request bodies using System.Xml.Serialization. The XmlReturn attribute can be used to expect XML responses. ```csharp public interface IUserApi { // POST with XML body [HttpPost("api/users")] Task PostByXmlAsync([XmlContent] User user, CancellationToken token = default); // Expect XML response [XmlReturn] [HttpGet("api/users/{id}")] Task GetExpectXmlAsync(string id); // Raw XML string content [HttpPost("api/users/raw")] Task PostRawXmlAsync([RawXmlContent] string xml); } // Usage var user = new User { Account = "john", Password = "secret" }; var result = await userApi.PostByXmlAsync(user); var xmlUser = await userApi.GetExpectXmlAsync(id: "user001"); ``` -------------------------------- ### Response Types Source: https://context7.com/dotnetcore/webapiclient/llms.txt Details on how to handle various response types, from raw HTTP messages to strongly-typed models. ```APIDOC ## GET /api/users/{account} (Raw HttpResponseMessage) ### Description Retrieves the raw HTTP response message. ### Method GET ### Endpoint /api/users/{account} ### Parameters #### Path Parameters - **account** (string) - Required - The account identifier. ### Response #### Success Response (200) - **HttpResponseMessage** - The raw HTTP response message. ## GET /api/users/{account} (String Response) ### Description Retrieves the response body as a string. ### Method GET ### Endpoint /api/users/{account} ### Parameters #### Path Parameters - **account** (string) - Required - The account identifier. ### Response #### Success Response (200) - **string** - The response body as a string. ## GET /api/users/{account} (Byte Array Response) ### Description Retrieves the response body as a byte array. ### Method GET ### Endpoint /api/users/{account} ### Parameters #### Path Parameters - **account** (string) - Required - The account identifier. ### Response #### Success Response (200) - **byte[]** - The response body as a byte array. ## GET /api/users/{account} (Stream Response) ### Description Retrieves the response body as a stream. ### Method GET ### Endpoint /api/users/{account} ### Parameters #### Path Parameters - **account** (string) - Required - The account identifier. ### Response #### Success Response (200) - **Stream** - The response body as a stream. ## GET /api/users/{account} (Model Response) ### Description Retrieves the response and deserializes it into a strongly-typed model. ### Method GET ### Endpoint /api/users/{account} ### Parameters #### Path Parameters - **account** (string) - Required - The account identifier. ### Response #### Success Response (200) - **User** (User) - The deserialized User object. ## GET /api/users/{account} (Explicit JSON Deserialization) ### Description Explicitly requests JSON deserialization for the response body into a User model. ### Method GET ### Endpoint /api/users/{account} ### Parameters #### Path Parameters - **account** (string) - Required - The account identifier. ### Response #### Success Response (200) - **User** (User) - The deserialized User object from the JSON response. ``` -------------------------------- ### Custom OAuth2 Token Placement Source: https://context7.com/dotnetcore/webapiclient/llms.txt Implement a custom OAuthTokenAttribute to control how the acquired token is used, such as placing it in a query parameter instead of the default header. ```csharp // Custom token placement (e.g., query parameter instead of header) public class UriQueryTokenAttribute : OAuthTokenAttribute { protected override void UseTokenResult(ApiRequestContext context, TokenResult tokenResult) { context.HttpContext.RequestMessage.AddUrlQuery("access_token", tokenResult.Access_token); } } [UriQueryToken] public interface IUserApi { [HttpGet("api/users/{id}")] Task GetAsync(string id); } ``` -------------------------------- ### OAuth2 Client Credentials Flow Source: https://context7.com/dotnetcore/webapiclient/llms.txt Configure the Client Credentials flow for OAuth2 token management by registering the interface with OAuthToken attribute and setting up the token provider with endpoint and credentials. ```csharp using WebApiClientCore.Extensions.OAuths; // Register interface with OAuth token support [OAuthToken] public interface IUserApi { [HttpGet("api/users/{id}")] Task GetAsync(string id); } // Configure Client Credentials flow services.AddHttpApi(); services.AddClientCredentialsTokenProvider(o => { o.Endpoint = new Uri("http://localhost:5000/api/tokens"); o.Credentials.Client_id = "clientId"; o.Credentials.Client_secret = "clientSecret"; }); ``` -------------------------------- ### POST with JSON Body Source: https://context7.com/dotnetcore/webapiclient/llms.txt Use the JsonContent attribute to serialize parameters as JSON request bodies. Supports System.Text.Json by default. ```csharp public interface IUserApi { // POST with JSON body [HttpPost("api/users")] Task PostByJsonAsync([JsonContent] User user, CancellationToken token = default); // Raw JSON string content [HttpPost("api/users/raw")] Task PostRawJsonAsync([RawJsonContent] string json); } // Usage var user = new User { Account = "john", Password = "secret" }; var result = await userApi.PostByJsonAsync(user); // With raw JSON await userApi.PostRawJsonAsync("{\"account\":\"john\",\"password\":\"secret\"}"); ``` -------------------------------- ### Form Content Requests Source: https://context7.com/dotnetcore/webapiclient/llms.txt Use FormContent for x-www-form-urlencoded data and FormDataContent for multipart/form-data with file uploads. Individual fields can be specified using FormField. ```csharp using WebApiClientCore.Parameters; public interface IUserApi { // x-www-form-urlencoded form [HttpPost("api/users/form")] Task PostByFormAsync([FormContent] User user, CancellationToken token = default); // multipart/form-data with file upload [HttpPost("api/users/formdata")] Task PostByFormDataAsync([FormDataContent] User user, FormDataFile file, CancellationToken token = default); // Form with constant fields [FormField("clientType", "mobile")] [FormField("version", "1.0")] [HttpPost("api/users")] Task PostWithConstantFieldsAsync([FormContent] User user); // Form with individual fields [HttpPost("api/login")] Task LoginAsync([FormField] string username, [FormField] string password); } // Usage var user = new User { Account = "john", Password = "secret" }; var formResult = await userApi.PostByFormAsync(user); // With file upload var file = new FormDataFile("path/to/file.txt"); var uploadResult = await userApi.PostByFormDataAsync(user, file); ``` -------------------------------- ### Logging Filter Configuration Source: https://context7.com/dotnetcore/webapiclient/llms.txt Shows how to enable request and response logging using the LoggingFilter attribute, including disabling logging for specific methods and implementing custom logging. ```APIDOC ## Logging Filter Enable request/response logging using the LoggingFilter attribute at interface or method level. ```csharp [LoggingFilter] // All methods log requests public interface IUserApi { [HttpGet("api/users/{id}")] Task GetAsync(string id); [LoggingFilter(Enable = false)] // Disable logging for this method [HttpPost("api/users")] Task PostAsync([JsonContent] User user); } // Custom logging implementation public class CustomLoggingAttribute : LoggingFilterAttribute { protected override Task WriteLogAsync(ApiResponseContext context, LogMessage logMessage) { // Output logMessage to your logging destination Console.WriteLine($"Request: {logMessage.RequestTime}"); Console.WriteLine($"Response: {logMessage.ResponseTime}"); return Task.CompletedTask; } } [CustomLogging] public interface IUserApi { // Methods use custom logging } ``` ``` -------------------------------- ### Use Injected HTTP API Client Source: https://context7.com/dotnetcore/webapiclient/llms.txt Inject registered HTTP API interfaces into services to make API calls. For singleton services, use IServiceScopeFactory to create a scope for obtaining the API client. ```csharp public class UserService { private readonly IUserApi userApi; public UserService(IUserApi userApi) { this.userApi = userApi; } public async Task RunRequestsAsync() { var user = new User { Account = "john_doe", Password = "123456", BirthDay = DateTime.Parse("1990-01-01"), Email = "john@example.com" }; // GET request with path parameter var fetchedUser = await userApi.GetAsync(id: "user001"); // POST request with JSON body var createdUser = await userApi.PostAsync(user); // PUT request with JSON body var updatedUser = await userApi.PutAsync(user); // DELETE request await userApi.DeleteAsync(id: "user001"); } } // For singleton services, use IServiceScopeFactory public class SingletonService { private readonly IServiceScopeFactory serviceScopeFactory; public SingletonService(IServiceScopeFactory serviceScopeFactory) { this.serviceScopeFactory = serviceScopeFactory; } public async Task GetUserAsync() { using var scope = serviceScopeFactory.CreateScope(); var userApi = scope.ServiceProvider.GetRequiredService(); var user = await userApi.GetAsync(id: "user001"); } } ``` -------------------------------- ### Exception Handling with Pattern Matching Source: https://context7.com/dotnetcore/webapiclient/llms.txt Handle request exceptions by pattern matching on HttpRequestException and its inner exceptions to catch specific API errors like configuration issues, status codes, general API errors, or network problems. ```csharp try { var user = await userApi.GetAsync(id: "001"); } catch (HttpRequestException ex) when (ex.InnerException is ApiInvalidConfigException configException) { // Invalid configuration exception Console.WriteLine($"Config error: {configException.Message}"); } catch (HttpRequestException ex) when (ex.InnerException is ApiResponseStatusException statusException) { // HTTP status code exception (4xx, 5xx) Console.WriteLine($"Status code: {statusException.StatusCode}"); } catch (HttpRequestException ex) when (ex.InnerException is ApiException apiException) { // General API exception Console.WriteLine($"API error: {apiException.Message}"); } catch (HttpRequestException ex) when (ex.InnerException is SocketException socketException) { // Network/socket exception Console.WriteLine($"Network error: {socketException.Message}"); } catch (HttpRequestException ex) { // General HTTP request exception Console.WriteLine($"Request failed: {ex.Message}"); } ``` -------------------------------- ### Custom Request Signing Filter Source: https://context7.com/dotnetcore/webapiclient/llms.txt Create a custom ApiFilterAttribute to implement request signing by obtaining a service from the provider and adding a signed value as a URL query parameter. ```csharp // Custom request signing filter public class SignFilterAttribute : ApiFilterAttribute { public override Task OnRequestAsync(ApiRequestContext context) { var signService = context.HttpContext.ServiceProvider.GetRequiredService(); var sign = signService.SignValue(DateTime.Now); context.HttpContext.RequestMessage.AddUrlQuery("sign", sign); return Task.CompletedTask; } } [SignFilter] public interface IUserApi { [HttpGet("api/users/{id}")] Task GetAsync(string id); } // Register filters programmatically services.AddHttpApi().ConfigureHttpApi(o => { o.GlobalFilters.Add(new SignFilterAttribute()); }); ``` -------------------------------- ### Request Headers Source: https://context7.com/dotnetcore/webapiclient/llms.txt Add static or dynamic headers using the Header attribute at interface, method, or parameter level. Supports multiple headers from an object or a custom headers class. ```csharp public interface IUserApi { // Constant headers on method [Header("X-Api-Version", "1.0")] [Header("X-Client-Type", "mobile")] [HttpGet("api/users/{id}")] Task GetAsync(string id); // Dynamic header from parameter [HttpGet("api/users/{id}")] Task GetWithAuthAsync(string id, [Header("Authorization")] string token); // Multiple headers from object [HttpGet("api/users/{id}")] Task GetWithHeadersAsync(string id, [Headers] Dictionary headers); // Custom headers class [HttpGet("api/users/{id}")] Task GetWithCustomHeadersAsync(string id, [Headers] CustomHeaders headers); } public class CustomHeaders { public string Authorization { get; set; } public string XRequestId { get; set; } } // Usage var user = await userApi.GetWithAuthAsync("001", "Bearer eyJhbGciOiJIUzI1NiIs..."); var headers = new Dictionary { ["Authorization"] = "Bearer token", ["X-Request-Id"] = Guid.NewGuid().ToString() }; var user2 = await userApi.GetWithHeadersAsync("001", headers); ``` -------------------------------- ### Implement Request Retry Source: https://context7.com/dotnetcore/webapiclient/llms.txt Enable request retry functionality by using the ITask return type. Retries can be configured with conditions based on exceptions or response values. ```csharp public interface IUserApi { [HttpGet("api/users/{id}")] ITask GetAsync(string id); } // Usage with retry var result = await userApi.GetAsync(id: "001") .Retry(maxCount: 3) .WhenCatch() .WhenResult(r => r == null || r.Account == null); // Retry on any exception var result2 = await userApi.GetAsync(id: "001") .Retry(maxCount: 3) .WhenCatch(); ``` -------------------------------- ### Define HTTP API Client Interface Source: https://context7.com/dotnetcore/webapiclient/llms.txt Declare HTTP API clients as C# interfaces using attributes to specify HTTP methods, routes, and content types. This interface will be automatically implemented and registered with dependency injection. ```csharp using WebApiClientCore; using WebApiClientCore.Attributes; [LoggingFilter] [HttpHost("http://localhost:5000/")] public interface IUserApi { [HttpGet("api/users/{id}")] Task GetAsync(string id); [HttpPost("api/users")] Task PostAsync([JsonContent] User user); [HttpPut("api/users")] Task PutAsync([JsonContent] User user); [HttpDelete("api/users/{id}")] Task DeleteAsync(string id); [HttpPatch("api/users/{id}")] Task PatchAsync(string id, JsonPatchDocument doc); } public class User { [JsonPropertyName("account")] public string Account { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; public DateTime BirthDay { get; set; } public string Email { get; set; } = string.Empty; } ``` -------------------------------- ### Response Types Source: https://context7.com/dotnetcore/webapiclient/llms.txt Supports various response types including raw HttpResponseMessage, string, byte array, Stream, and strongly-typed models. Explicit JSON deserialization can be enforced with JsonReturn. ```csharp public interface IUserApi { // Raw HttpResponseMessage [HttpGet("api/users/{account}")] ITask GetAsync(string account); // String response [HttpGet("api/users/{account}")] ITask GetAsStringAsync(string account, CancellationToken token = default); // Byte array response [HttpGet("api/users/{account}")] ITask GetAsByteArrayAsync(string account, CancellationToken token = default); // Stream response [HttpGet("api/users/{account}")] ITask GetAsStreamAsync(string account, CancellationToken token = default); // Strongly-typed model [HttpGet("api/users/{account}")] ITask GetAsModelAsync(string account, CancellationToken token = default); // Explicit JSON deserialization [JsonReturn] [HttpGet("api/users/{account}")] ITask GetExpectJsonAsync(string account, CancellationToken token = default); } ``` -------------------------------- ### OAuth2 Password Flow Source: https://context7.com/dotnetcore/webapiclient/llms.txt Configure the Password flow for OAuth2 token management by registering the interface with OAuthToken attribute and setting up the token provider with endpoint, credentials, username, and password. ```csharp // Configure Password flow services.AddPasswordCredentialsTokenProvider(o => { o.Endpoint = new Uri("http://localhost:5000/api/tokens"); o.Credentials.Client_id = "clientId"; o.Credentials.Client_secret = "clientSecret"; o.Credentials.Username = "username"; o.Credentials.Password = "password"; }); ``` -------------------------------- ### Configure Request Timeout Source: https://context7.com/dotnetcore/webapiclient/llms.txt Set request timeouts at the method level using constant values or at the parameter level for dynamic values. Supports integer milliseconds and TimeSpan objects. ```csharp public interface IUserApi { // Constant timeout (10 seconds) [Timeout(10 * 1000)] [HttpGet("api/users/{id}")] Task GetAsync(string id); // Dynamic timeout from parameter [HttpGet("api/users/{id}")] Task GetAsync(string id, [Timeout] int timeoutMilliseconds); // Using TimeSpan parameter [HttpGet("api/users/{id}")] Task GetAsync(string id, [Timeout] TimeSpan timeout); } // Usage var user = await userApi.GetAsync("001", timeoutMilliseconds: 5000); var user2 = await userApi.GetAsync("001", timeout: TimeSpan.FromSeconds(30)); ``` -------------------------------- ### Form Content Requests Source: https://context7.com/dotnetcore/webapiclient/llms.txt Covers sending form data using x-www-form-urlencoded and multipart/form-data, including file uploads and constant fields. ```APIDOC ## POST /api/users/form (Form Content) ### Description Sends a POST request with data formatted as x-www-form-urlencoded. ### Method POST ### Endpoint /api/users/form ### Parameters #### Request Body - **user** (User) - Required - The user object to be serialized as form data. ### Request Example ``` account=john&password=secret ``` ### Response #### Success Response (200) - **User** (User) - The deserialized User object from the response. ## POST /api/users/formdata (Form Data with File) ### Description Sends a POST request with multipart/form-data, including a file upload. ### Method POST ### Endpoint /api/users/formdata ### Parameters #### Request Body - **user** (User) - Required - The user object to be included in the form data. - **file** (FormDataFile) - Required - The file to upload. ### Response #### Success Response (200) - **User** (User) - The deserialized User object from the response. ## POST /api/users (Form with Constant Fields) ### Description Sends a POST request with form data including predefined constant fields. ### Method POST ### Endpoint /api/users ### Parameters #### Request Body - **user** (User) - Required - The user object to be serialized as form data. ### Request Example ``` clientType=mobile&version=1.0&account=john&password=secret ``` ### Response #### Success Response (200) - **User** (User) - The deserialized User object from the response. ## POST /api/login (Form with Individual Fields) ### Description Handles user login by sending username and password as individual form fields. ### Method POST ### Endpoint /api/login ### Parameters #### Request Body - **username** (string) - Required - The username for login. - **password** (string) - Required - The password for login. ### Response #### Success Response (200) - **TokenResult** (TokenResult) - The result containing the authentication token. ``` -------------------------------- ### Configure Response Caching Source: https://context7.com/dotnetcore/webapiclient/llms.txt Cache API responses using the Cache attribute with a specified duration. The request URI serves as the cache key. Demonstrates custom cache provider registration with Redis. ```csharp // Cache for 60 seconds [Cache(60 * 1000)] [HttpGet("api/users/{id}")] Task GetAsync(string id); ``` ```csharp // Custom cache provider registration public static IWebApiClientBuilder UseRedisResponseCacheProvider(this IWebApiClientBuilder builder) { builder.Services.AddSingleton(); return builder; } public class RedisResponseCacheProvider : IResponseCacheProvider { public string Name => nameof(RedisResponseCacheProvider); public Task GetAsync(string key) { // Retrieve from Redis throw new NotImplementedException(); } public Task SetAsync(string key, ResponseCacheEntry entry, TimeSpan expiration) { // Store in Redis throw new NotImplementedException(); } } ``` -------------------------------- ### Custom Protobuf Response Content Attribute Source: https://context7.com/dotnetcore/webapiclient/llms.txt Define a custom attribute to handle Protobuf content for API responses. This attribute reads the response stream, deserializes it into the expected return type using Protobuf, and sets it as the API result. ```csharp // Custom response content attribute for Protobuf public class ProtobufReturnAttribute : ApiReturnAttribute { public ProtobufReturnAttribute() : base(new MediaTypeWithQualityHeaderValue("application/x-protobuf")) { } public override async Task SetResultAsync(ApiResponseContext context) { var stream = await context.HttpContext.ResponseMessage.Content.ReadAsStreamAsync(); context.Result = Serializer.NonGeneric.Deserialize( context.ApiAction.Return.DataType.Type, stream); } } ``` -------------------------------- ### Custom Protobuf Request Content Attribute Source: https://context7.com/dotnetcore/webapiclient/llms.txt Define a custom attribute to handle Protobuf content for API requests. This attribute serializes the parameter value to a Protobuf stream and sets it as the request content with the appropriate content type. ```csharp // Custom request content attribute for Protobuf public class ProtobufContentAttribute : HttpContentAttribute { public string ContentType { get; set; } = "application/x-protobuf"; protected override Task SetHttpContentAsync(ApiParameterContext context) { var stream = new MemoryStream(); if (context.ParameterValue != null) { Serializer.NonGeneric.Serialize(stream, context.ParameterValue); stream.Position = 0L; } var content = new StreamContent(stream); content.Headers.ContentType = new MediaTypeHeaderValue(ContentType); context.HttpContext.RequestMessage.Content = content; return Task.CompletedTask; } } ``` -------------------------------- ### Data Validation with Attributes Source: https://context7.com/dotnetcore/webapiclient/llms.txt Use standard ValidationAttribute classes like EmailAddress, Required, and StringLength to validate request parameters and response models. Disable validation globally in configuration if needed. ```csharp using System.ComponentModel.DataAnnotations; public interface IUserApi { [HttpGet("api/users/{email}")] Task GetByEmailAsync( [EmailAddress, Required] string email); [HttpPost("api/users")] Task PostAsync([Required][JsonContent] User user); } public class User { [Required] [StringLength(50, MinimumLength = 1)] public string Account { get; set; } [Required] [StringLength(100, MinimumLength = 6)] public string Password { get; set; } [EmailAddress] public string Email { get; set; } } // Disable validation in configuration services.AddHttpApi().ConfigureHttpApi(o => { o.UseParameterPropertyValidate = false; o.UseReturnValuePropertyValidate = false; }); ``` -------------------------------- ### Request Retry Mechanism Source: https://context7.com/dotnetcore/webapiclient/llms.txt Details how to implement request retries using the ITask return type, allowing retries based on exceptions or response conditions. ```APIDOC ## Request Retry Use ITask return type to enable retry functionality with conditions based on exceptions or response values. ```csharp public interface IUserApi { [HttpGet("api/users/{id}")] ITask GetAsync(string id); } // Usage with retry var result = await userApi.GetAsync(id: "001") .Retry(maxCount: 3) .WhenCatch() .WhenResult(r => r == null || r.Account == null); // Retry on any exception var result2 = await userApi.GetAsync(id: "001") .Retry(maxCount: 3) .WhenCatch(); ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.