6.11自定义对象内容转换器(如序列化)
创建于 2026 年 8 月 17 日约 2 分钟读完
IObjectContentConverterFactory 默认的内容转换器工厂会返回 ObjectContentConverter 实例,该实例利用 HttpResponseMessage.Content 的 ReadFromJsonAsync 方法,结合 System.Text.Json 序列化库,将 HttpRequestMessage 对象转换为目标接收类型。然而,这种转换方式在某些特殊类型(例如 DataTable)上可能会遇到反序列化失败的问题。为了应对这种情况,您可以自定义 ObjectContentConverter,以便选择或更换为更适合您需求的 JSON 序列化工具(例如 Newtonsoft.Json)。
自定义时需同时提供泛型和非泛型版本:
// 非泛型版本public class CustomObjectContentConverter : ObjectContentConverter{ /// <inheritdoc /> public override async Task<object?> ReadAsync(Type resultType, HttpContentConverterContext context, CancellationToken cancellationToken = default) { // 获取 HttpResponseMessage 实例 var httpResponseMessage = context.ResponseMessage; // 解析 HttpClient 客户端对应的 JSON 序列化上下文信息 var jsonSerializationContext = HttpRemoteUtility.ResolveJsonSerializationContext(resultType, httpResponseMessage, ServiceProvider); // 获取 JSON 反序列化的值(若需使用 Newtonsoft.Json 进行序列化或反序列化操作,请将以下代码替换为 Newtonsoft.Json 库的相应方法调用) ✅✅✅ var deserializedValue = await httpResponseMessage.Content.ReadFromJsonAsync(jsonSerializationContext.ResultType, jsonSerializationContext.JsonSerializerOptions, cancellationToken); // 获取转换的目标类型值 return jsonSerializationContext.GetResultValue(deserializedValue, httpResponseMessage); }}// 泛型版本public class CustomObjectContentConverter<TResult> : CustomObjectContentConverter, IHttpContentConverter<TResult>{ /// <inheritdoc /> public virtual TResult? Read(HttpContentConverterContext context, CancellationToken cancellationToken = default) => (TResult?)base.Read(typeof(TResult), context, cancellationToken); /// <inheritdoc /> public virtual async Task<TResult?> ReadAsync(HttpContentConverterContext context, CancellationToken cancellationToken = default) => (TResult?)await base.ReadAsync(typeof(TResult), context, cancellationToken);}接着,创建自定义的 IObjectContentConverterFactory 实现:
public sealed class CustomObjectContentConverterFactory : IObjectContentConverterFactory{ /// <inheritdoc /> public IHttpContentConverter<TResult> GetConverter<TResult>(HttpContentConverterContext context) { // 检查 HTTP 响应的内容类型是否为 XML 媒体类型 if (context.ResponseMessage.IsXmlContent()) { return new XmlObjectContentConverter<TResult>(); } return new CustomObjectContentConverter<TResult>(); } /// <inheritdoc /> public IHttpContentConverter GetConverter(Type resultType, HttpContentConverterContext context) { // 检查 HTTP 响应的内容类型是否为 XML 媒体类型 if (context.ResponseMessage.IsXmlContent()) { return new XmlObjectContentConverter(); } return new CustomObjectContentConverter(); }}最后,在 Startup.cs 或 Program.cs 文件中,配置并注册 HttpRemote 服务,以替换默认的对象内容转换器工厂功能:
services.AddHttpRemote(builder =>{ builder.UseObjectContentConverterFactory<CustomObjectContentConverterFactory>();});这样,通过自定义的 ObjectContentConverter 和 IObjectContentConverterFactory 工厂,可以确保在反序列化时使用指定的 JSON 选项,避免潜在的反序列化问题。