You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现高性能的自定义CosmosSerializer以在序列化/反序列化时修剪字符串值的空白

如何实现高性能的自定义CosmosSerializer以在序列化/反序列化时修剪字符串值的空白

针对你的需求,最高效的方案是利用Newtonsoft.Json的自定义JsonConverter来处理字符串的空白修剪,而不是用反射遍历属性。这种方式是序列化框架原生支持的扩展点,性能远优于手动反射,而且能自动覆盖所有嵌套的字符串属性,实现全局的空白修剪。

核心思路

通过创建一个专门处理字符串类型的JsonConverter,在序列化和反序列化的过程中自动修剪字符串前后的空白,然后将这个转换器注册到Newtonsoft的JsonSerializer实例中,让Cosmos的序列化流程自动应用这个逻辑。

第一步:实现字符串修剪的JsonConverter

这个转换器只负责处理字符串类型的序列化/反序列化,逻辑非常聚焦:

public class StringTrimmingConverter : JsonConverter<string>
{
    public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 读取原始字符串并修剪前后空白,避免空引用异常
        var rawValue = reader.Value as string;
        return rawValue?.Trim();
    }

    public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
    {
        // 写入前先修剪空白,同样处理null情况
        writer.WriteValue(value?.Trim());
    }
}

第二步:修改CustomCosmosSerializer,注册转换器

把上面的转换器添加到JsonSerializer的转换器集合中,这样所有字符串类型的属性都会自动应用修剪逻辑:

public class CustomCosmosSerializer : CosmosSerializer
{
    private readonly Newtonsoft.Json.JsonSerializer _serializer;

    public CustomCosmosSerializer()
    {
        _serializer = new Newtonsoft.Json.JsonSerializer();
        // 注册自定义字符串修剪转换器,全局生效
        _serializer.Converters.Add(new StringTrimmingConverter());
    }

    public override T FromStream<T>(Stream stream)
    {
        using var streamReader = new StreamReader(stream);
        using var jsonTextReader = new JsonTextReader(streamReader);
        return _serializer.Deserialize<T>(jsonTextReader);
    }

    public override Stream ToStream<T>(T input)
    {
        var memoryStream = new MemoryStream();
        // 保持流打开,避免提前释放导致Cosmos读取失败
        using var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8, leaveOpen: true);
        using var jsonTextWriter = new JsonTextWriter(streamWriter);
        _serializer.Serialize(jsonTextWriter, input);
        // 重置流位置到开头,确保Cosmos客户端能正确读取内容
        memoryStream.Position = 0;
        return memoryStream;
    }
}

方案优势

  1. 性能更优:JsonConverter是Newtonsoft.Json的原生扩展,序列化引擎会直接调用转换器处理字符串类型,完全避免了反射遍历属性的开销,在处理大量文档时性能差异会非常明显。
  2. 全局覆盖:不管是根对象的字符串属性,还是嵌套对象、数组中的字符串,都会自动应用修剪逻辑,不需要手动处理每个层级。
  3. 代码简洁易维护:转换器只关注字符串修剪逻辑,CosmosSerializer只负责整合序列化流程,职责清晰,后续修改也很方便。

额外细节优化

  • 修正了你原代码中RequestTimeout的小问题:new TimeSpan(10)表示的是10个时间刻度(约1微秒),这显然不是你想要的,应该改为TimeSpan.FromSeconds(10)来设置10秒超时。
  • 如果后续需要对某些特定字符串跳过修剪,可以给对应的属性加上[JsonConverter(typeof(StringConverter))](使用默认的字符串转换器),覆盖全局的修剪逻辑。

最终CosmosClient初始化代码

var cosmosClientOptions = new CosmosClientOptions
{
    ConnectionMode = ConnectionMode.Direct,
    RequestTimeout = TimeSpan.FromSeconds(10),
    Serializer = new CustomCosmosSerializer()
};

private readonly CosmosClient _cosmosClient = new CosmosClient(uri, key, cosmosClientOptions);

备注:内容来源于stack exchange,提问作者ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 08:48:10