Mud.HttpUtils 序列化器适配包
Mud.HttpUtils 的所有 JSON / XML 序列化都经过 IHttpContentSerializer 抽象。默认实现为 SystemTextJsonContentSerializer(基于 System.Text.Json),可通过以下两个适配包替换为其它序列化引擎。
| 包 | 实现 | 依赖 | Native AOT |
|---|---|---|---|
Mud.HttpUtils.Newtonsoft.Json | NewtonsoftJsonContentSerializer | Newtonsoft.Json 13.0.4 | ❌ 不支持 |
Mud.HttpUtils.Xml | XmlContentSerializer | System.Xml.Serialization.XmlSerializer | ❌ 不支持 |
二者均只依赖
Mud.HttpUtils.Abstractions(IHttpContentSerializer/ISynchronousContentSerializer接口定义)。
Mud.HttpUtils.Newtonsoft.Json
提供基于 Newtonsoft.Json.JsonSerializer 的 IHttpContentSerializer 实现(NewtonsoftJsonContentSerializer)。该实现同时实现了同步序列化接口 ISynchronousContentSerializer,并支持流式请求体写入。
安装
dotnet add package Mud.HttpUtils.Newtonsoft.Json用法
在 DI 中将默认的 JSON 序列化器替换为 Newtonsoft.Json(可传入自定义 JsonSerializerSettings):
services.AddMudHttpClient<ICatalogApi>(options =>
{
options.BaseAddress = new Uri("https://api.example.com/");
options.ContentSerializer = new NewtonsoftJsonContentSerializer(new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.None
});
});不传参数时使用默认的 JsonSerializerSettings,也可通过 Settings 属性在初始化后读取或自行构造:
var serializer = new NewtonsoftJsonContentSerializer();
string json = serializer.Serialize(new Order { Id = 1 });
var order = serializer.Deserialize<Order>(json);字段名映射
实现 IHttpContentSerializer.GetFieldNameForProperty,识别属性上的 [JsonProperty("...")] 特性名称,供生成器在查询参数等场景下映射字段名。
同步与流式序列化
该序列化器实现了 ISynchronousContentSerializer:
- 同步请求体:
ToHttpContentSynchronous<T>直接通过JsonConvert.SerializeObject生成内容; - 流式请求体:
ToStreamingHttpContent<T>返回流式内容,在发送时以JsonSerializer逐步写入请求流,适用于大对象请求体场景。
Native AOT 限制(重要)
Newtonsoft.Json 依赖反射与动态代码,不支持 Native AOT 与裁剪。本包所有公共成员均已标注 [RequiresUnreferencedCode](复合类型序列化重载额外标注 [RequiresDynamicCode]),消费方在启用 AOT/裁剪分析器时会在调用点获得编译期提示。本包自身已设置 IsAotCompatible=false 并关闭 AOT/裁剪分析器的"已知噪声"。
Native AOT 场景请使用 Mud.HttpUtils.Client 内置的 SystemTextJsonContentSerializer + JsonSerializerContext(源生成 JSON 序列化)。
接口成员对照
| 接口 | 方法 | 说明 |
|---|---|---|
IHttpContentSerializer | ToHttpContent<T> | 序列化对象为 UTF-8 application/json 的 StringContent |
IHttpContentSerializer | FromHttpContentAsync<T> | 从响应流反序列化为对象 |
IHttpContentSerializer | Serialize<T> / Serialize(object, Type) | 序列化为 JSON 字符串 |
IHttpContentSerializer | Deserialize<T> | 从 JSON 字符串反序列化 |
IHttpContentSerializer | GetFieldNameForProperty | 读取 [JsonProperty] 字段名 |
ISynchronousContentSerializer | ToHttpContentSynchronous<T> | 同步生成请求内容 |
ISynchronousContentSerializer | ToStreamingHttpContent<T> | 生成流式请求内容 |
Mud.HttpUtils.Xml
提供基于 System.Xml.Serialization.XmlSerializer 的 IHttpContentSerializer 实现(XmlContentSerializer)。
安装
dotnet add package Mud.HttpUtils.Xml用法
在 DI 中将默认的 JSON 序列化器替换为 XML:
services.AddMudHttpClient<ICatalogApi>(options =>
{
options.BaseAddress = new Uri("https://api.example.com/");
options.ContentSerializer = new XmlContentSerializer(new XmlContentSerializerSettings
{
MediaType = "application/xml",
WriterSettings = new XmlWriterSettings
{
Encoding = Encoding.UTF8,
Indent = true,
OmitXmlDeclaration = false
}
});
});也可脱离 DI 独立使用(实现 IHttpContentSerializer 的全部方法):
var serializer = new XmlContentSerializer();
string xml = serializer.Serialize(new Order { Id = 1 });
var order = serializer.Deserialize<Order>(xml);Native AOT 限制(重要)
XmlSerializer 在运行时生成动态程序集,不支持 Native AOT 与裁剪。本包所有公共成员均已标注 [RequiresDynamicCode] 与 [RequiresUnreferencedCode],消费方在启用 AOT 分析器时会在调用点获得编译期提示。
Native AOT 场景请使用 Mud.HttpUtils.Client 内置的 SystemTextJsonContentSerializer + JsonSerializerContext(源生成 JSON 序列化)。
此外,源代码生成器在 AOT 上下文下检测到 XML 序列化时会发出 AOT007(确认 Native AOT 时为 Error),详见源代码生成器文档。
定位说明:与生成客户端内置 XML 路径的关系
| 入口 | 机制 | 适用场景 |
|---|---|---|
XmlContentSerializer(本包) | IHttpContentSerializer DI 抽象 | 请求体序列化引擎替换(如 [SerializationMethod(SerializationMethod.Xml)]) |
| 生成客户端内置路径 | ResponseDescriptor.XmlSerializer 元数据直通(源生成器发射 XmlSerializer 字段) | 生成的客户端方法的 XML 响应反序列化 |
二者互补、不互相替代。注意两条路径均基于 XmlSerializer(反射),均不受 Native AOT 支持。
建议
- 默认保持
System.Text.Json(默认 AOT 安全、零反射)。 - 仅当需要 Newtonsoft.Json 特有行为(
JsonProperty复杂转换、遗留契约兼容)或 XML 协议对接时才引入适配包。 - 引入前确认目标部署形态:启用
PublishAot/IsAotCompatible的项目不要引用这两个包。