Mud.HttpUtils.Generator
1.7.1
See the version list below for details.
dotnet add package Mud.HttpUtils.Generator --version 1.7.1
NuGet\Install-Package Mud.HttpUtils.Generator -Version 1.7.1
<PackageReference Include="Mud.HttpUtils.Generator" Version="1.7.1" />
<PackageVersion Include="Mud.HttpUtils.Generator" Version="1.7.1" />
<PackageReference Include="Mud.HttpUtils.Generator" />
paket add Mud.HttpUtils.Generator --version 1.7.1
#r "nuget: Mud.HttpUtils.Generator, 1.7.1"
#:package Mud.HttpUtils.Generator@1.7.1
#addin nuget:?package=Mud.HttpUtils.Generator&version=1.7.1
#tool nuget:?package=Mud.HttpUtils.Generator&version=1.7.1
Mud.HttpUtils.Generator
概述
Mud.HttpUtils.Generator 是一个基于 Roslyn 的源代码生成器,自动为标记了 [HttpClientApi] 特性的接口生成 HttpClient 实现类。支持多种 HTTP 方法、灵活的参数处理、内容类型管理、Token 认证、请求/响应加密等功能。
功能特性
核心功能
- 自动代码生成:根据接口定义自动生成 HttpClient 实现
- HTTP 方法支持:支持 GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS 等 HTTP 方法
- 参数处理:自动处理 Path、Query、Header、Body、FormContent 等参数类型
- Token 管理:支持多种 Token 类型(TenantAccessToken、UserAccessToken、AppAccessToken),TokenType 使用字符串类型,解耦强绑定
- HttpClient 模式:支持通过
HttpClient属性直接注入 HttpClient 接口,与TokenManage互斥 - 依赖注入:自动生成服务注册扩展方法
- 类型安全:强类型的 API 调用,编译时检查
高级功能
- 内容类型管理:支持接口级、方法级、参数级的内容类型配置,优先级清晰
- 请求/响应类型分离:支持请求和响应使用不同的内容类型(如请求 XML、响应 JSON)
- 请求体加密:支持请求体数据加密传输
- 响应解密:支持响应数据自动解密
- 文件下载:支持大文件下载和二进制数据下载
- 表单数据:支持 multipart/form-data 格式
- 数组查询参数:支持数组类型的查询参数
快速开始
1. 定义 API 接口
[HttpClientApi("https://api.example.com", Timeout = 60)]
public interface IExampleApi
{
// GET 请求
[Get("/users/{id}")]
Task<UserInfo> GetUserAsync([Path] int id);
// POST 请求(JSON)
[Post("/users")]
Task<UserInfo> CreateUserAsync([Body] CreateUserRequest request);
// GET 请求(查询参数)
[Get("/users")]
Task<List<UserInfo>> GetUsersAsync([Query] string? name = null, [Query] int page = 1);
// 文件下载
[Get("/files/{fileId}")]
Task DownloadFileAsync([Path] string fileId, [FilePath] string savePath);
}
2. 注册服务
// 在 Program.cs 或 Startup.cs 中
services.AddWebApiHttpClient();
3. 使用 API
public class UserService
{
private readonly IExampleApi _api;
public UserService(IExampleApi api)
{
_api = api;
}
public async Task<UserInfo> GetUserAsync(int id)
{
return await _api.GetUserAsync(id);
}
}
特性详解
HttpClientApi 特性
用于标记需要生成 HTTP 客户端实现的接口。
[HttpClientApi(
baseAddress: "https://api.example.com", // API 基础地址(已弃用)
ContentType = "application/json", // 默认请求内容类型
Timeout = 50, // 超时时间(秒)
TokenManage = "ITokenManager", // Token 管理器接口
HttpClient = "IMyHttpClient", // HttpClient 接口(与 TokenManage 互斥,优先)
RegistryGroupName = "Example", // 注册组名称
IsAbstract = false, // 是否生成抽象类
InheritedFrom = "BaseClass" // 继承的基类
)]
public interface IExampleApi { }
注意:
HttpClient与TokenManage属性互斥,同时定义时HttpClient优先。
HTTP 方法特性
所有 HTTP 方法特性都支持以下属性:
[Post(
"/api/users", // 请求路径
ContentType = "application/json", // 请求内容类型
ResponseContentType = "application/xml",// 响应内容类型
ResponseEnableDecrypt = false // 响应是否启用解密
)]
Task<UserInfo> CreateUserAsync([Body] UserRequest request);
支持的 HTTP 方法:
[Get]- GET 请求[Post]- POST 请求[Put]- PUT 请求[Delete]- DELETE 请求[Patch]- PATCH 请求[Head]- HEAD 请求[Options]- OPTIONS 请求
内容类型优先级
内容类型(ContentType)支持三级配置,优先级从高到低:
Body 参数级 > 方法级 > 接口级 > 默认值 (application/json)
// 接口级:application/xml
[HttpClientApi("https://api.example.com", ContentType = "application/xml")]
public interface IContentTypeApi
{
// 使用接口级设置:application/xml
[Post("/api/test1")]
Task<Response> Test1Async([Body] Request data);
// 方法级覆盖:application/json
[Post("/api/test2", ContentType = "application/json")]
Task<Response> Test2Async([Body] Request data);
// Body 参数级优先级最高:text/plain
[Post("/api/test3", ContentType = "application/json")]
Task<Response> Test3Async([Body(ContentType = "text/plain")] Request data);
}
请求/响应类型分离
支持请求和响应使用不同的内容类型:
// 请求 XML,响应 JSON
[Post("/api/xml-to-json")]
Task<JsonResponse> PostXmlGetJsonAsync([Body("application/xml")] XmlRequest request);
// 请求 JSON,响应 XML
[Post("/api/json-to-xml", ResponseContentType = "application/xml")]
Task<XmlResponse> PostJsonGetXmlAsync([Body] JsonRequest request);
参数特性
Path 参数
[Get("/users/{id}/posts/{postId}")]
Task<Post> GetPostAsync([Path] int id, [Path] int postId);
Query 参数
[Get("/users")]
Task<List<User>> GetUsersAsync(
[Query] string? name = null,
[Query] int page = 1,
[Query] int pageSize = 20
);
数组 Query 参数
[Get("/users")]
Task<List<User>> GetUsersAsync(
[ArrayQuery] int[] ids, // 默认分号分隔
[ArrayQuery(Separator = ",")] string[] tags // 逗号分隔
);
Header 参数
[Get("/users")]
Task<User> GetUserAsync([Header("X-Custom-Header")] string customValue);
Body 参数
// 基本 Body 参数
[Post("/users")]
Task<User> CreateUserAsync([Body] UserRequest request);
// 指定内容类型
[Post("/users")]
Task<User> CreateUserAsync([Body("application/xml")] UserRequest request);
// 启用加密
[Post("/users")]
Task<User> CreateUserAsync(
[Body(
ContentType = "application/json",
EnableEncrypt = true,
EncryptSerializeType = SerializeType.Json,
EncryptPropertyName = "data"
)] UserRequest request
);
// 原始字符串内容
[Post("/content")]
Task PostContentAsync([Body(RawString = true)] string content);
FilePath 参数(文件下载)
[Get("/files/{fileId}")]
Task DownloadFileAsync([Path] string fileId, [FilePath(BufferSize = 81920)] string savePath);
FormContent 参数(表单数据)
[Post("/upload")]
Task UploadAsync([FormContent] IFormContent formData);
Token 认证
TokenAttribute 的 TokenType 属性使用字符串类型,支持以下值:
"TenantAccessToken"- 租户访问令牌"UserAccessToken"- 用户访问令牌"AppAccessToken"- 应用访问令牌
使用示例:
// 接口级设置 Token 类型
[Token("TenantAccessToken")]
public interface IMyApi { }
// 参数级设置 Token 类型
[Get("/users/{id}")]
Task<User> GetUserAsync([Path] int id, [Token("UserAccessToken")] string? token = null);
// 使用命名参数
[Token(TokenType = "AppAccessToken")]
public interface IAppApi { }
Token 注入模式
public enum TokenInjectionMode
{
Header, // 注入到 HTTP Header
Query, // 注入到 URL Query 参数
Path // 注入到 URL Path
}
[Token("TenantAccessToken", InjectionMode = TokenInjectionMode.Header, Name = "Authorization")]
HttpClient 模式
当 HttpClientApiAttribute 设置了 HttpClient 属性时,生成的代码不会包含 Token 相关的字段和方法,而是直接注入指定的 HttpClient 接口实例:
[HttpClientApi(HttpClient = "IMyHttpClient")]
public interface IMyApi
{
[Get("/users")]
Task<List<User>> GetUsersAsync();
}
// 生成的代码大致结构:
// internal partial class MyApi : IMyApi
// {
// private readonly IMyHttpClient _httpClient;
// ...
// public MyApi(IOptions<JsonSerializerOptions> option, IMyHttpClient httpClient)
// {
// _httpClient = httpClient;
// }
// // 不生成 _tokenType、_appManager、GetTokenAsync 等 Token 相关代码
// }
响应解密
[Post("/api/secure-data", ResponseEnableDecrypt = true)]
Task<SecureData> GetSecureDataAsync([Body] Request request);
项目结构
Mud.HttpUtils.Generator/
├── Analyzers/ # 代码分析器
│ ├── MethodAnalyzer.cs # 方法分析
│ └── ParameterAnalyzer.cs # 参数分析
├── Generators/ # 代码生成器
│ ├── Implementation/
│ │ └── RequestBuilder.cs # 请求构建
│ ├── HttpInvokeClassSourceGenerator.cs
│ └── HttpInvokeRegistrationGenerator.cs
├── Helpers/ # 辅助类
│ ├── MethodHelper.cs
│ └── AttributeDataHelper.cs
├── Models/ # 数据模型
│ └── Analysis/
│ └── MethodAnalysisResult.cs
└── README.md
依赖项
- .NET Standard 2.0
- Microsoft.CodeAnalysis.Analyzers
- Microsoft.CodeAnalysis.CSharp
版本历史
1.7.0
TokenAttribute.TokenType从枚举类型改为字符串类型,解耦强绑定HttpClientApiAttribute新增HttpClient属性,支持直接注入 HttpClient 接口HttpClient与TokenManage互斥,同时定义时HttpClient优先- HttpClient 模式下不生成 Token 相关的字段和方法
1.6.3
- 移除 HttpContentTypeAttribute 特性,简化内容类型管理
- 扩展 HttpMethodAttribute,新增 ContentType 属性
- 优化响应内容类型处理逻辑,请求/响应类型完全分离
- 修复响应 ContentType 错误回退到请求 ContentType 的问题
1.0.0
- 初始版本
- 从 Mud.ServiceCodeGenerator 项目中独立出来
- 支持基本的 HTTP API 代码生成功能
许可证
本项目遵循 MIT 许可证。详细信息请参见 LICENSE 文件。
贡献
欢迎提交 Issue 和 Pull Request 来改进这个项目。
相关项目
- Mud.CodeGenerator - 基础代码生成框架
- Mud.EntityCodeGenerator - 实体代码生成器
- Mud.ServiceCodeGenerator - 服务代码生成器
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0-rc2 | 121 | 5/13/2026 |
| 2.0.0-rc1 | 161 | 5/9/2026 |
| 2.0.0-preview6 | 125 | 5/6/2026 |
| 2.0.0-preview5 | 99 | 5/3/2026 |
| 2.0.0-preview4 | 187 | 4/30/2026 |
| 2.0.0-preview3 | 90 | 4/29/2026 |
| 2.0.0-preview2 | 120 | 4/28/2026 |
| 2.0.0-preview1 | 91 | 4/27/2026 |
| 1.7.1 | 236 | 5/12/2026 |
| 1.7.0 | 392 | 4/12/2026 |
| 1.6.7 | 103 | 4/11/2026 |
| 1.6.6 | 138 | 4/8/2026 |
| 1.6.5 | 143 | 4/5/2026 |
| 1.6.4 | 103 | 4/2/2026 |
| 1.6.3 | 103 | 3/21/2026 |
| 1.6.2 | 109 | 3/17/2026 |
| 1.6.1 | 105 | 3/16/2026 |
| 1.6.0 | 112 | 3/13/2026 |