### Complete .csproj File Example for AOT
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
A comprehensive example of a .csproj file configured for AOT publishing, including necessary package references and build properties.
```xml
Exe
net8.0
enable
true
true
true
```
--------------------------------
### New: Full Interface Example
Source: https://webapiclient.github.io/guide/advanced/migration-guide.html
The equivalent full interface example using WebApiClientCore, showcasing updated attributes, parameter types, and return types.
```csharp
using WebApiClientCore;
using System.Text.Json.Serialization;
[LoggingFilter]
[HttpHost("https://petstore.swagger.io/v2/")]
public interface IPetApi
{
[HttpPost("pet")]
Task AddPetAsync([JsonContent] Pet body, CancellationToken token = default);
[HttpGet("pet/findByStatus")]
Task> FindPetsByStatusAsync(IEnumerable status, CancellationToken token = default);
[HttpGet("pet/{petId}")]
Task GetPetByIdAsync(long petId, CancellationToken token = default);
[HttpPost("pet/{petId}/uploadImage")]
Task UploadFileAsync(long petId, [FormDataText] string additionalMetadata, FormDataFile file, CancellationToken token = default);
}
```
--------------------------------
### Basic JsonRpc Call Example
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
A complete example demonstrating how to define a user API interface with JsonRpc methods and make calls to add, get, and list users.
```csharp
// 定义用户模型
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
// 定义 RPC 接口
[HttpHost("http://localhost:5000/jsonrpc")]
public interface IUserApi
{
[JsonRpcMethod("user.add")]
ITask> AddUserAsync([JsonRpcParam] string name, [JsonRpcParam] int age);
[JsonRpcMethod("user.get")]
ITask> GetUserAsync([JsonRpcParam] int id);
[JsonRpcMethod("user.list")]
ITask>> ListUsersAsync();
}
// 调用示例
var api = HttpApi.Create();
// 添加用户
var addResult = await api.AddUserAsync("张三", 25);
if (addResult.Error == null)
{
Console.WriteLine($"用户ID: {addResult.Result}");
}
// 获取用户
var getResult = await api.GetUserAsync(1);
if (getResult.Error == null)
{
Console.WriteLine($"用户名: {getResult.Result.Name}");
}
```
--------------------------------
### Complete WebApiClientCore Configuration Example
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
A full example demonstrating how to configure WebApiClientCore, including registering the JSON source generator context and HTTP API interfaces, within a .NET generic host application.
```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
class Program
{
static void Main(string[] args)
{
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
// 配置 WebApiClientCore
services
.AddWebApiClient()
.ConfigureHttpApi(options =>
{
options.PrependJsonSerializerContext(AppJsonSerializerContext.Default);
});
// 注册 HTTP API 接口
services.AddHttpApi();
// 注册后台服务
services.AddHostedService();
})
.Build()
.Run();
}
}
```
--------------------------------
### Old: Full Interface Example
Source: https://webapiclient.github.io/guide/advanced/migration-guide.html
A comprehensive example of an interface declaration using the old WebApiClient, demonstrating various attributes and types.
```csharp
using WebApiClient;
using WebApiClient.Attributes;
using WebApiClient.Parameterables;
[TraceFilter]
[HttpHost("https://petstore.swagger.io/v2/")]
public interface IPetApi : IHttpApi
{
[HttpPost("pet")]
ITask AddPetAsync([Required] [JsonContent] Pet body);
[HttpGet("pet/findByStatus")]
ITask> FindPetsByStatusAsync([Required] IEnumerable status);
[HttpGet("pet/{petId}")]
ITask GetPetByIdAsync([Required] long petId);
[HttpPost("pet/{petId}/uploadImage")]
ITask UploadFileAsync([Required] long petId, [MulitpartContent] string additionalMetadata, MulitpartFile file);
}
```
--------------------------------
### Complete AOT Publish Command Example
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
A comprehensive example of the 'dotnet publish' command, including common AOT-specific options like trimming, globalization invariant mode, symbol stripping, and optimization preferences.
```bash
# 完整发布命令示例
dotnet publish -c Release -r linux-x64 \
-p:PublishAot=true \
-p:PublishTrimmed=true \
-p:InvariantGlobalization=true \
-p:StripSymbols=true \
-p:OptimizationPreference=Speed
```
--------------------------------
### Main Program Entry Point
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
The main program entry point sets up the .NET generic host, configures services including WebApiClientCore and HTTP API interfaces, and starts the application.
```csharp
// Program.cs
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
class Program
{
static void Main(string[] args)
{
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services
.AddWebApiClient()
.ConfigureHttpApi(options =>
{
options.PrependJsonSerializerContext(AppJsonSerializerContext.Default);
});
services.AddHttpApi();
services.AddHostedService();
})
.Build()
.Run();
}
}
```
--------------------------------
### Full Example: Basic Call
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Demonstrates how to define and use a JSON-RPC client interface with WebApiClientCore, including making calls and handling responses.
```APIDOC
## 完整示例
### 示例 1:基础调用
```csharp
// 定义用户模型
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
// 定义 RPC 接口
[HttpHost("http://localhost:5000/jsonrpc")]
public interface IUserApi
{
[JsonRpcMethod("user.add")]
ITask> AddUserAsync([JsonRpcParam] string name, [JsonRpcParam] int age);
[JsonRpcMethod("user.get")]
ITask> GetUserAsync([JsonRpcParam] int id);
[JsonRpcMethod("user.list")]
ITask>> ListUsersAsync();
}
// 调用示例
var api = HttpApi.Create();
// 添加用户
var addResult = await api.AddUserAsync("张三", 25);
if (addResult.Error == null)
{
Console.WriteLine($"用户ID: {addResult.Result}");
}
// 获取用户
var getResult = await api.GetUserAsync(1);
if (getResult.Error == null)
{
Console.WriteLine($"用户名: {getResult.Result.Name}");
}
```
```
--------------------------------
### Install JsonRpc Extension Package
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Add the JsonRpc extension package to your project using the .NET CLI.
```bash
dotnet add package WebApiClientCore.Extensions.JsonRpc
```
--------------------------------
### Generated Proxy Class Example
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
This code shows an example of a proxy class generated by the WebApiClientCore Source Generator for an IHttpApi interface. It demonstrates how the interface methods are implemented to use an interceptor.
```csharp
// HttpApiProxyClass.IUserApi.g.cs
namespace WebApiClientCore
{
partial class HttpApiProxyClass
{
[HttpApiProxyClass(typeof(IUserApi))]
sealed partial class IUserApi : IUserApi
{
private readonly IHttpApiInterceptor _apiInterceptor;
private readonly ApiActionInvoker[] _actionInvokers;
public IUserApi(IHttpApiInterceptor apiInterceptor, ApiActionInvoker[] actionInvokers)
{
_apiInterceptor = apiInterceptor;
_actionInvokers = actionInvokers;
}
[HttpApiProxyMethod(0, "GetAsync", typeof(IUserApi))]
Task IUserApi.GetAsync(string p0)
{
return (Task)_apiInterceptor.Intercept(_actionInvokers[0], new object[] { p0 });
}
}
}
}
```
--------------------------------
### Retry Delay Strategies
Source: https://webapiclient.github.io/guide/configuration/retry-policy.html
Examples demonstrating different delay strategies for retries, including fixed delay, exponential backoff, linear increment, and custom logic based on the day of the week.
```csharp
// 固定延时:每次重试前等待 1 秒
await userApi.GetByIdAsync("id001")
.Retry(3, TimeSpan.FromSeconds(1));
// 指数退避:1s, 2s, 4s...
await userApi.GetByIdAsync("id001")
.Retry(3, i => TimeSpan.FromSeconds(Math.Pow(2, i)));
// 线性递增:1s, 2s, 3s...
await userApi.GetByIdAsync("id001")
.Retry(3, i => TimeSpan.FromSeconds(i + 1));
// 自定义策略:基于工作日/周末不同延时
await userApi.GetByIdAsync("id001")
.Retry(3, i =>
{
var now = DateTime.Now;
return now.DayOfWeek == DayOfWeek.Saturday || now.DayOfWeek == DayOfWeek.Sunday
? TimeSpan.FromSeconds(5)
: TimeSpan.FromSeconds(1);
});
```
--------------------------------
### Old: Basic Interface Declaration
Source: https://webapiclient.github.io/guide/advanced/migration-guide.html
Example of a basic interface declaration using the old WebApiClient.
```csharp
using WebApiClient;
using WebApiClient.Attributes;
public interface IUserApi : IHttpApi
{
[HttpGet("api/user")]
ITask GetAsync(string account);
[HttpPost("api/user")]
ITask AddAsync([FormContent] UserInfo user);
}
```
--------------------------------
### New: Basic Interface Declaration
Source: https://webapiclient.github.io/guide/advanced/migration-guide.html
Example of a basic interface declaration using the new WebApiClientCore, including attributes and default cancellation token.
```csharp
using WebApiClientCore;
[LoggingFilter]
[HttpHost("http://localhost:5000/")]
public interface IUserApi
{
[HttpGet("api/user")]
Task GetAsync(string account, CancellationToken token = default);
[HttpPost("api/user")]
Task AddAsync([FormContent] UserInfo user, CancellationToken token = default);
}
```
--------------------------------
### JsonRpcParamsStyle.Object Example
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Illustrates the Object parameter serialization style for JSON-RPC calls, where parameters are sent as a named object.
```csharp
[JsonRpcMethod("getUser", ParamsStyle = JsonRpcParamsStyle.Object)]
ITask> GetUserAsync([JsonRpcParam] string name, [JsonRpcParam] int age);
```
```json
{"jsonrpc":"2.0","method":"getUser","params":{"name":"张三","age":18},"id":2}
```
--------------------------------
### WhenCatch Usage Examples
Source: https://webapiclient.github.io/guide/configuration/retry-policy.html
Demonstrates various scenarios for using WhenCatch, including catching specific exceptions like HttpRequestException, logging exceptions, retrying based on inner exceptions, handling multiple exception types, and asynchronous exception handling.
```csharp
// 场景1:捕获 HttpRequestException 并重试
var result = await userApi.GetByIdAsync("id001")
.Retry(3)
.WhenCatch();
// 场景2:捕获异常后记录日志
var result = await userApi.GetByIdAsync("id001")
.Retry(3)
.WhenCatch(ex =>
{
logger.LogWarning(ex, "请求失败,准备重试");
});
// 场景3:仅当特定条件满足时才重试
var result = await userApi.GetByIdAsync("id001")
.Retry(3)
.WhenCatch(ex =>
{
// 仅网络相关异常重试
return ex.InnerException is SocketException;
});
// 场景4:捕获多种异常类型
var result = await userApi.GetByIdAsync("id001")
.Retry(3)
.WhenCatch()
.WhenCatch()
.WhenCatch();
// 场景5:异步异常处理
var result = await userApi.GetByIdAsync("id001")
.Retry(3)
.WhenCatchAsync(async ex =>
{
await auditService.LogRetryAttemptAsync(ex);
});
```
--------------------------------
### JsonRpcParamsStyle.Array Example
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Demonstrates the Array parameter serialization style for JSON-RPC calls, where parameters are sent as a positional array.
```csharp
[JsonRpcMethod("add", ParamsStyle = JsonRpcParamsStyle.Array)]
ITask> AddAsync([JsonRpcParam] int a, [JsonRpcParam] int b);
```
```json
{"jsonrpc":"2.0","method":"add","params":[1,2],"id":1}
```
--------------------------------
### Project Structure for AOT Application
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
An example project structure for an AOT-compiled application using WebApiClientCore. This includes the main project file, program entry point, JSON serializer context, API interface, data models, and service implementations.
```plaintext
AppAot/
├── AppAot.csproj
├── Program.cs
├── AppJsonSerializerContext.cs
├── IUserApi.cs
├── User.cs
└── AppService.cs
```
--------------------------------
### HTTP API Interface Definition
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Defines the IUserApi interface for interacting with a user API. It includes attributes for logging, setting the base host, and defining HTTP methods (GET, POST) with associated routes and content types.
```csharp
// IUserApi.cs
using WebApiClientCore.Attributes;
[LoggingFilter]
[HttpHost("https://api.example.com")]
public interface IUserApi
{
[HttpGet("api/users/{id}")]
Task GetUserAsync(string id);
[HttpPost("api/users")]
Task CreateUserAsync([JsonContent] User user);
[HttpGet("api/users")]
Task ListUsersAsync();
}
```
--------------------------------
### Old: Static Configuration Registration
Source: https://webapiclient.github.io/guide/advanced/migration-guide.html
Demonstrates the old way of registering and configuring WebApiClient using static methods.
```csharp
using WebApiClient;
// Old: Register and configure using static methods
HttpApi.Register().ConfigureHttpApiConfig(c =>
{
c.HttpHost = new Uri("http://www.webapiclient.com/");
c.FormatOptions.DateTimeFormat = DateTimeFormats.ISO8601_WithMillisecond;
});
// Old: Get instance using static methods
var api = HttpApi.Resolve();
```
--------------------------------
### Module Initializer Registration for Proxy Classes
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
This generated code snippet demonstrates the use of `[ModuleInitializer]` and `[DynamicDependency]` attributes to ensure that the generated proxy classes are registered and available at runtime, preventing them from being trimmed.
```csharp
// HttpApiProxyClass.g.cs
static partial class HttpApiProxyClass
{
[ModuleInitializer]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(HttpApiProxyClass))]
public static void Initialize()
{
}
}
```
--------------------------------
### New: Dependency Injection Configuration
Source: https://webapiclient.github.io/guide/advanced/migration-guide.html
Shows the new method for configuring WebApiClientCore using dependency injection in Startup or ServiceCollection.
```csharp
using WebApiClientCore;
using Microsoft.Extensions.DependencyInjection;
// New: Configure in Startup or ServiceCollection
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpApi().ConfigureHttpApi(o =>
{
o.HttpHost = new Uri("http://www.webapiclient.com/");
o.UseLogging = Environment.IsDevelopment();
// json serialization options
o.JsonSerializeOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
o.JsonDeserializeOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
}
// New: Inject via constructor
public class YourService
{
private readonly IUserApi userApi;
public YourService(IUserApi userApi)
{
this.userApi = userApi;
}
}
```
--------------------------------
### Basic AOT Publish Command
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Use the 'dotnet publish' command with the Release configuration to publish your application as a self-contained AOT application for the current platform.
```bash
# 发布为当前平台的 AOT 应用
dotnet publish -c Release
```
--------------------------------
### Configure AOT Publishing Properties in .csproj
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Set these properties in your .csproj file to configure your project for AOT publishing. This includes enabling AOT compilation, trimming, and optionally using invariant globalization for reduced size.
```xml
Exe
net8.0
true
true
true
```
--------------------------------
### Import JsonRpc Namespaces
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Include these namespaces when using the JsonRpc extension for attributes and result types.
```csharp
using WebApiClientCore.Attributes; // JsonRpcMethodAttribute, JsonRpcParamAttribute, JsonRpcParamsStyle
using WebApiClientCore.Extensions.JsonRpc; // JsonRpcResult, JsonRpcError
```
--------------------------------
### Publish Output Directory Structure
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
The output of the 'dotnet publish' command for AOT applications is located in the 'bin/Release/net8.0//publish/' directory. Key files include the executable and PDB symbols (if not stripped).
```bash
# 发布输出位于
bin/Release/net8.0//publish/
# 主要文件
# - <应用名> (可执行文件)
# - <应用名>.pdb (调试符号,如果未剥离)
```
--------------------------------
### JsonRpcMethodAttribute Constructors
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Use these constructors to define JSON-RPC methods, optionally specifying the RPC method name and request path.
```csharp
[JsonRpcMethod("methodName")]
```
```csharp
[JsonRpcMethod("methodName", "/rpc/path")]
```
--------------------------------
### Await ITask Directly
Source: https://webapiclient.github.io/guide/configuration/retry-policy.html
ITask is awaitable and fully compatible with Task. It can be directly awaited or used with ConfigureAwait for controlling synchronization context.
```csharp
// ITask 可以直接 await
ITask task = userApi.GetByIdAsync("id001");
User user = await task;
// 支持 ConfigureAwait
User user = await userApi.GetByIdAsync("id001").ConfigureAwait(false);
```
--------------------------------
### WebApiClientCore NuGet Package References
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Add these NuGet packages to your project to enable WebApiClientCore and its Source Generator for AOT compatibility. The analyzer package must be referenced with OutputItemType='Analyzer' and ReferenceOutputAssembly='false'.
```xml
```
--------------------------------
### Handling ApiInvalidConfigException
Source: https://webapiclient.github.io/guide/configuration/exception-handling.html
Handle configuration errors by catching HttpRequestException and checking for ApiInvalidConfigException. Configuration errors should typically be fixed during development.
```csharp
try
{
var user = await api.GetUserAsync();
}
catch (HttpRequestException ex) when (ex.InnerException is ApiInvalidConfigException configEx)
{
Console.WriteLine($"Configuration error: {configEx.Message}");
// Configuration errors should be fixed during development, not ignored at runtime
throw;
}
```
--------------------------------
### ITask vs Task Return Types
Source: https://webapiclient.github.io/guide/configuration/retry-policy.html
Choose ITask for scenarios requiring conditional retries, default value handling on exceptions, or fluent API chaining. Use Task for simple requests without retry needs.
```csharp
public interface IUserApi
{
// 返回 Task - 标准异步模式
[HttpGet("api/users/{id}")]
Task GetAsync(string id);
// 返回 ITask - 支持链式调用
[HttpGet("api/users/{id}")]
ITask GetByIdAsync(string id);
}
```
--------------------------------
### Register JSON Source Generator Context
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Register the JsonSerializerContext in your dependency injection configuration. Use PrependJsonSerializerContext to add your custom context before the default ones.
```csharp
using Microsoft.Extensions.DependencyInjection;
services
.AddWebApiClient()
.ConfigureHttpApi(options =>
{
// 注册 JSON 源生成上下文
options.PrependJsonSerializerContext(AppJsonSerializerContext.Default);
});
```
--------------------------------
### WhenCatch Method Signatures
Source: https://webapiclient.github.io/guide/configuration/retry-policy.html
WhenCatch allows specifying exception types to trigger retries. It supports direct retries, handling exceptions before retrying, or using a predicate to conditionally retry.
```csharp
// 捕获指定类型异常,直接重试
IRetryTask WhenCatch() where TException : Exception
// 捕获异常后执行处理逻辑,然后重试
IRetryTask WhenCatch(Action handler) where TException : Exception
// 捕获异常后判断是否需要重试
IRetryTask WhenCatch(Func predicate) where TException : Exception
// 异步版本:捕获异常后执行异步处理
IRetryTask WhenCatchAsync(Func handler) where TException : Exception
// 异步版本:捕获异常后异步判断是否需要重试
IRetryTask WhenCatchAsync(Func> predicate) where TException : Exception
```
--------------------------------
### User Data Model
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Defines the User data model with properties for Id, Name, and Email. It uses JsonPropertyName attributes to map C# properties to JSON field names.
```csharp
// User.cs
using System.Text.Json.Serialization;
public class User
{
[JsonPropertyName("id")]
public string Id { get; set; } = string.Empty;
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
[JsonPropertyName("email")]
public string? Email { get; set; }
}
```
--------------------------------
### JsonRpcResult Structure
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Defines the structure for handling JSON-RPC responses, including success results and errors.
```csharp
public class JsonRpcResult
{
///
/// 请求 id
///
public int? Id { get; set; }
///
/// json rpc 版本号
///
public string JsonRpc { get; set; }
///
/// 结果值(成功时)
///
public TResult Result { get; set; }
///
/// 错误内容(失败时)
///
public JsonRpcError? Error { get; set; }
}
```
--------------------------------
### JsonRpcResult Response Handling
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Represents a JSON-RPC 2.0 response, containing either a result or an error.
```APIDOC
## 响应处理:JsonRpcResult
JSON-RPC 响应通过 `JsonRpcResult` 泛型类接收:
```csharp
public class JsonRpcResult
{
///
/// 请求 id
///
public int? Id { get; set; }
///
/// json rpc 版本号
///
public string JsonRpc { get; set; }
///
/// 结果值(成功时)
///
public TResult Result { get; set; }
///
/// 错误内容(失败时)
///
public JsonRpcError? Error { get; set; }
}
```
```
--------------------------------
### Specify Target Platform for AOT Publish
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Specify the target runtime identifier (RID) when publishing your AOT application to ensure compatibility with the desired operating system and architecture.
```bash
# 指定目标平台
dotnet publish -c Release -r win-x64
dotnet publish -c Release -r linux-x64
dotnet publish -c Release -r osx-x64
dotnet publish -c Release -r osx-arm64
```
--------------------------------
### Retry Method Overloads
Source: https://webapiclient.github.io/guide/configuration/retry-policy.html
The Retry extension method on ITask returns IRetryTask and allows configuring retry conditions. Overloads support specifying maximum retry count, fixed delay, or a dynamic delay function.
```csharp
// 最大重试次数
IRetryTask Retry(this ITask task, int maxCount)
// 最大重试次数 + 固定延时
IRetryTask Retry(this ITask task, int maxCount, TimeSpan delay)
// 最大重试次数 + 动态延时
IRetryTask Retry(this ITask task, int maxCount, Func? delay)
```
--------------------------------
### JSON Source Generator Context Definition
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Defines the AppJsonSerializerContext for JSON source generation, specifying the User type and User array as serializable types. This is a partial class that will be implemented by the source generator.
```csharp
// AppJsonSerializerContext.cs
using System.Text.Json.Serialization;
[JsonSerializable(typeof(User))]
[JsonSerializable(typeof(User[]))]
public partial class AppJsonSerializerContext : JsonSerializerContext
{
}
```
--------------------------------
### Define JsonSerializerContext for AOT
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Create a partial class that derives from `JsonSerializerContext` and uses the `[JsonSerializable]` attribute to specify the types that will be serialized or deserialized. This is crucial for AOT compatibility with `System.Text.Json`.
```csharp
using System.Text.Json.Serialization;
[JsonSerializable(typeof(User))]
[JsonSerializable(typeof(User[]))]
[JsonSerializable(typeof(Order))]
[JsonSerializable(typeof(Order[]))]
// 添加所有接口中使用的 JSON 模型类型
public partial class AppJsonSerializerContext : JsonSerializerContext
{
}
```
--------------------------------
### JsonRpcParamsStyle Parameter Styles
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Defines the serialization style for parameters in JSON-RPC requests: Array (positional) and Object (named).
```APIDOC
## JsonRpcParamsStyle 参数风格
`JsonRpcParamsStyle` 枚举定义了参数序列化的三种模式:
### Array 模式(默认)
参数按位置序列化为数组:
```csharp
[JsonRpcMethod("add", ParamsStyle = JsonRpcParamsStyle.Array)]
ITask> AddAsync([JsonRpcParam] int a, [JsonRpcParam] int b);
```
生成的请求:
```json
{"jsonrpc":"2.0","method":"add","params":[1,2],"id":1}
```
### Object 模式
参数按名称序列化为对象:
```csharp
[JsonRpcMethod("getUser", ParamsStyle = JsonRpcParamsStyle.Object)]
ITask> GetUserAsync([JsonRpcParam] string name, [JsonRpcParam] int age);
```
生成的请求:
```json
{"jsonrpc":"2.0","method":"getUser","params":{"name":"张三","age":18},"id":2}
```
### 选择建议
模式| 适用场景
---|---
Array| 服务端按位置解析参数,参数数量固定
Object| 服务端按名称解析参数,参数可选或顺序不固定
```
--------------------------------
### Handling ApiResponseStatusException
Source: https://webapiclient.github.io/guide/configuration/exception-handling.html
Handle HTTP errors by catching HttpRequestException and checking for ApiResponseStatusException. This allows inspection of the status code and response message for detailed error handling.
```csharp
try
{
var user = await api.GetUserAsync(1);
}
catch (HttpRequestException ex) when (ex.InnerException is ApiResponseStatusException statusEx)
{
var statusCode = (int)statusEx.StatusCode;
var reasonPhrase = statusEx.ResponseMessage.ReasonPhrase;
Console.WriteLine($"HTTP Error: {statusCode} {reasonPhrase}");
// Can read response content for detailed error information
var errorContent = await statusEx.ResponseMessage.Content.ReadAsStringAsync();
Console.WriteLine($"Error details: {errorContent}");
// Classify and handle based on status code
switch (statusCode)
{
case 401:
// Unauthorized, may require re-authentication
break;
case 403:
// Forbidden
break;
case 404:
// Resource not found
break;
case >= 500:
// Server error
break;
}
}
```
--------------------------------
### Declare JSON Source Generator Context
Source: https://webapiclient.github.io/guide/advanced/aot-publishing.html
Declare all JSON data types used in interfaces, including element and collection types for collections, and specific generic parameters for generic types. This is required for the JSON source generator.
```csharp
// 示例:完整的 JSON 类型声明
[JsonSerializable(typeof(User))]
[JsonSerializable(typeof(User[]))]
[JsonSerializable(typeof(List))]
[JsonSerializable(typeof(ApiResponse))]
[JsonSerializable(typeof(ApiResponse>))]
public partial class AppJsonSerializerContext : JsonSerializerContext
{
}
```
--------------------------------
### Catching Specific ApiException Types
Source: https://webapiclient.github.io/guide/configuration/exception-handling.html
Catch HttpRequestException and use a 'when' clause to specifically handle ApiException subclasses like ApiInvalidConfigException.
```csharp
catch (HttpRequestException ex) when (ex.InnerException is ApiException apiException)
{
// Catch all WebApiClientCore internal exceptions
logger.LogError(apiException, "API call failed");
}
```
--------------------------------
### JsonRpcError Structure
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Represents a JSON-RPC error response, containing code, message, and optional data.
```csharp
public class JsonRpcError
{
///
/// 错误码
///
public int Code { get; set; }
///
/// 提示消息
///
public string? Message { get; set; }
///
/// 错误详情
///
public object? Data { get; set; }
}
```
--------------------------------
### Standard JSON-RPC Error Codes
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
A list of standard error codes defined by the JSON-RPC 2.0 specification.
```APIDOC
### 标准 JSON-RPC 错误码
错误码| 含义
---|---
-32700| 解析错误(Parse error)
-32600| 无效请求(Invalid Request)
-32601| 方法不存在(Method not found)
-32602| 无效参数(Invalid params)
-32603| 内部错误(Internal error)
-32000 ~ -32099| 服务端自定义错误
```
--------------------------------
### WhenResult Method Signatures
Source: https://webapiclient.github.io/guide/configuration/retry-policy.html
WhenResult allows retrying based on the response result. It provides synchronous and asynchronous predicate functions to evaluate the result and determine if a retry is needed.
```csharp
// 同步判断
IRetryTask WhenResult(Func predicate)
// 异步判断
IRetryTask WhenResultAsync(Func> predicate)
```
--------------------------------
### JsonRpcMethodAttribute Usage
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
The JsonRpcMethodAttribute marks an interface method for JSON-RPC invocation. It can be used with or without specifying the RPC method name and path.
```APIDOC
## JsonRpcMethodAttribute
`JsonRpcMethodAttribute` 用于标记接口方法为 JSON-RPC 调用,它继承自 `HttpPostAttribute` 并实现了 `IApiFilterAttribute`。
### 构造函数
构造函数| 说明
---|---
`JsonRpcMethodAttribute()`| 使用方法名作为 RPC 方法名
`JsonRpcMethodAttribute(string method)`| 指定 RPC 方法名
`JsonRpcMethodAttribute(string method, string path)`| 指定 RPC 方法名和请求路径
### 属性
属性| 类型| 默认值| 说明
---|---|---|---
`ContentType`| string| `application/json-rpc`| 请求的 Content-Type
`ParamsStyle`| JsonRpcParamsStyle| `Array`| 参数序列化风格
### 工作原理
1. **OnRequestAsync** :初始化 `JsonRpcParameters` 容器
2. **IApiFilter.OnRequestAsync** :收集参数后构建 JSON-RPC 请求体
3. 方法名默认使用接口方法名,可通过构造函数指定
```
--------------------------------
### Catching HttpRequestException with Inner ApiException
Source: https://webapiclient.github.io/guide/configuration/exception-handling.html
Catch HttpRequestException and check if the InnerException is an ApiException for unified handling of WebApiClientCore internal errors.
```csharp
try
{
var data = await api.GetAsync();
}
catch (HttpRequestException ex)
{
// ex.InnerException is the actual exception
Console.WriteLine($"Actual exception type: {ex.InnerException?.GetType().Name}");
}
```
--------------------------------
### JsonRpcParamAttribute Usage
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
The JsonRpcParamAttribute marks method parameters to be included in the JSON-RPC 'params' field. It must be used in conjunction with JsonRpcMethodAttribute.
```APIDOC
## JsonRpcParamAttribute
`JsonRpcParamAttribute` 用于标记方法参数为 JSON-RPC 参数。被标记的参数会被收集到参数列表中,最终序列化为 `params` 字段。
### 使用规则
* 必须与 `JsonRpcMethodAttribute` 配合使用
* 参数按声明顺序收集
* 未标记的参数(如 `CancellationToken`)不会参与 RPC 调用
```
--------------------------------
### JsonRpcError Structure
Source: https://webapiclient.github.io/guide/extensions/jsonrpc-extension.html
Represents a JSON-RPC error object, including code, message, and optional data.
```APIDOC
### 错误处理:JsonRpcError
```csharp
public class JsonRpcError
{
///
/// 错误码
///
public int Code { get; set; }
///
/// 提示消息
///
public string? Message { get; set; }
///
/// 错误详情
///
public object? Data { get; set; }
}
```
```
--------------------------------
### Handling ApiResultNotMatchException
Source: https://webapiclient.github.io/guide/configuration/exception-handling.html
Handle cases where retry conditions based on results fail after exhausting retries. This exception contains the last result that failed the condition.
```csharp
try
{
var result = await api.GetDataAsync()
.Retry(3)
.WhenResult(r => r.Success == false);
}
catch (HttpRequestException ex) when (ex.InnerException is ApiResultNotMatchException resultEx)
{
Console.WriteLine($"Result validation failed, retries exhausted");
Console.WriteLine($"Last result: {resultEx.Result}");
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.