6.11自定义对象内容转换器(如序列化)

创建于 2026 年 8 月 17 日约 2 分钟读完

IObjectContentConverterFactory 默认的内容转换器工厂会返回 ObjectContentConverter 实例,该实例利用 HttpResponseMessage.ContentReadFromJsonAsync 方法,结合 System.Text.Json 序列化库,将 HttpRequestMessage 对象转换为目标接收类型。然而,这种转换方式在某些特殊类型(例如 DataTable)上可能会遇到反序列化失败的问题。为了应对这种情况,您可以自定义 ObjectContentConverter,以便选择或更换为更适合您需求的 JSON 序列化工具(例如 Newtonsoft.Json)。

自定义时需同时提供泛型和非泛型版本:

cs
// 非泛型版本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 实现:

cs
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.csProgram.cs 文件中,配置并注册 HttpRemote 服务,以替换默认的对象内容转换器工厂功能:

cs
services.AddHttpRemote(builder =>{    builder.UseObjectContentConverterFactory<CustomObjectContentConverterFactory>();});

这样,通过自定义的 ObjectContentConverterIObjectContentConverterFactory 工厂,可以确保在反序列化时使用指定的 JSON 选项,避免潜在的反序列化问题。