向Azure Cosmos DB添加文档时自定义扩展属性缺失如何解决
根本原因
你遇到的属性丢失问题是序列化器不统一导致的:
- Stripe官方的
BalanceTransaction基类使用的是Newtonsoft.Json的[JsonProperty]特性,且基类StripeEntity默认开启了MemberSerialization.OptIn配置,只有标注了Newtonsoft.Json序列化特性的属性才会被序列化。 - 你自定义的子类属性使用的是System.Text.Json的
[JsonPropertyName]特性,你自己调用JsonSerializer.Serialize(System.Text.Json类库的方法)时能正常识别这两个特性,所以打印的JSON是完整的。 - Azure Cosmos DB .NET SDK V3及更早版本默认使用Newtonsoft.Json作为内部序列化器,在执行
CreateItemAsync时会用Newtonsoft.Json重新序列化你的对象,这时候你自定义的两个属性没有标注Newtonsoft.Json的序列化特性,就会被过滤掉,最终存入Cosmos DB的文档就缺少了这两个字段。
解决方案
方案1:统一使用Newtonsoft.Json的特性(最简单)
直接修改你的CustomBalanceTransaction类,给自定义属性加上Newtonsoft.Json的[JsonProperty]特性,和基类的序列化规则保持一致:
public class CustomBalanceTransaction : BalanceTransaction { [JsonProperty("customerid")] public string Customerid { get; set; } [JsonProperty("import_status")] public MiddlewareStatus ImportStatus { get; set; } }
修改后无需改动其他代码,直接插入就能正常保留自定义属性。
方案2:将Cosmos DB SDK的序列化器改为System.Text.Json
如果你不想引入Newtonsoft.Json的特性,可以在初始化CosmosClient的时候配置序列化器,让Cosmos SDK使用System.Text.Json做序列化,和你自己的序列化逻辑保持一致:
var clientOptions = new CosmosClientOptions { Serializer = new SystemTextJsonSerializer(new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 可补充其他你需要的序列化配置 }) }; var cosmosClient = new CosmosClient(connectionString, clientOptions);
注意SystemTextJsonSerializer是Azure Cosmos DB SDK 3.23.0版本之后才内置支持的,如果你用的版本更低,可以自己实现CosmosSerializer接口封装System.Text.Json。
方案3:直接插入已序列化的JSON内容
你已经得到了完整的JSON字符串,可以直接将字符串转换成字节流插入,跳过Cosmos SDK的对象序列化步骤:
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); using var response = await transactionContainer.CreateItemAsync<dynamic>( /*替换为你实际的分区键*/, stream);
内容的提问来源于stack exchange,提问作者cel0x
相关产品推荐
相关产品推荐

