Mud.HttpUtils.Generator 1.7.1

There is a newer prerelease version of this package available.
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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Mud.HttpUtils.Generator" Version="1.7.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Mud.HttpUtils.Generator" Version="1.7.1" />
                    
Directory.Packages.props
<PackageReference Include="Mud.HttpUtils.Generator" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Mud.HttpUtils.Generator --version 1.7.1
                    
#r "nuget: Mud.HttpUtils.Generator, 1.7.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Mud.HttpUtils.Generator@1.7.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Mud.HttpUtils.Generator&version=1.7.1
                    
Install as a Cake Addin
#tool nuget:?package=Mud.HttpUtils.Generator&version=1.7.1
                    
Install as a Cake Tool

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 { }

注意HttpClientTokenManage 属性互斥,同时定义时 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 认证

TokenAttributeTokenType 属性使用字符串类型,支持以下值:

  • "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 接口
  • HttpClientTokenManage 互斥,同时定义时 HttpClient 优先
  • HttpClient 模式下不生成 Token 相关的字段和方法

1.6.3

  • 移除 HttpContentTypeAttribute 特性,简化内容类型管理
  • 扩展 HttpMethodAttribute,新增 ContentType 属性
  • 优化响应内容类型处理逻辑,请求/响应类型完全分离
  • 修复响应 ContentType 错误回退到请求 ContentType 的问题

1.0.0

  • 初始版本
  • 从 Mud.ServiceCodeGenerator 项目中独立出来
  • 支持基本的 HTTP API 代码生成功能

许可证

本项目遵循 MIT 许可证。详细信息请参见 LICENSE 文件。

贡献

欢迎提交 Issue 和 Pull Request 来改进这个项目。

相关项目

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .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