我是否过度简化了通过流将JSON序列化到Azure Blob的操作?
问题
我在SO上找到了一段通过流将C#对象序列化到Azure Blob的代码,这段2018年的代码采用NewtonSoft JSON序列化方案,于是我决定修改代码使其适配System.Text.Json。修改后的代码简洁太多,我担心自己过度简化,后续会引发问题。基于流的System.Text.Json序列化真的像看起来这么简单吗?
新代码同时兼容AppendBlobClient和BlockBlobClient,此处展示AppendBlobClient示例是因为它更贴合我的应用场景。
新代码
public static class BlobExtensions { public static async Task AppendObjectAsJsonAsync( this AppendBlobClient blob, object obj ) { using var stream = await blob.OpenWriteAsync( false ); await JsonSerializer.SerializeAsync( stream, obj ); } }
原NewtonSoft代码
public static class BlobExtensions { public static async Task SerializeObjectToBlobAsync(this CloudBlockBlob blob, object obj) { using (Stream stream = await blob.OpenWriteAsync()) using (StreamWriter sw = new StreamWriter(stream)) using (JsonTextWriter jtw = new JsonTextWriter(sw)) { JsonSerializer ser = new JsonSerializer(); ser.Serialize(jtw, obj); } } }
回答
你的简化代码是没问题的,但要注意几个和原NewtonSoft代码的差异点,避免踩坑:
编码一致性:原代码的StreamWriter默认用UTF-8无BOM编码,System.Text.Json的
SerializeAsync默认也是用UTF-8无BOM写入,这点两者行为一致,不需要额外处理。但如果你的场景需要其他编码,System.Text.Json需要配合自定义编码的流来实现,和NewtonSoft的方式不同。序列化配置差异:NewtonSoft和System.Text.Json的默认序列化规则有细微差别,需要对齐原代码的配置:
- 空值处理:两者默认都会序列化null属性,如果原代码有忽略null的配置,你需要在
SerializeAsync中传入JsonSerializerOptions并设置DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull。 - 命名策略:如果原代码用了驼峰命名转换,需要在
JsonSerializerOptions中设置PropertyNamingPolicy = JsonNamingPolicy.CamelCase。 - 枚举、日期格式等:如果原代码有自定义处理逻辑,要确保System.Text.Json的对应配置和之前一致。
- 空值处理:两者默认都会序列化null属性,如果原代码有忽略null的配置,你需要在
流的生命周期:原代码嵌套三层using管理资源,新代码用
using var自动管理流的生命周期,JsonSerializer.SerializeAsync会确保所有数据写入流后才完成,Azure Blob的流在释放时会自动提交写入,这个逻辑是可靠的。
内容的提问来源于stack exchange,提问作者camelCase
相关产品推荐
相关产品推荐

