CosmosDb插入操作报BadRequest(400)错误,求排查原因
CosmosDB插入400 BadRequest错误排查与解决
核心问题排查方向
1. 容器实际分区键是否与代码配置一致
CreateContainerIfNotExistsAsync仅在容器不存在时执行创建逻辑,如果之前你已经创建过分区键不同的phoneBooks容器,后续调用不会修改已有容器的分区键配置。直接去Azure门户数据资源管理器查看容器的分区键设置,确认是否为/id。如果不符,删除容器后重新执行创建代码,或者调整插入逻辑匹配现有分区键。
2. 对象序列化后的字段名是否匹配分区键路径
C#对象的Id属性默认会被JSON序列化器(System.Text.Json/Newtonsoft.Json)转为小写的id,这和你设置的分区键/id是匹配的,但如果你的序列化配置被修改过(比如强制保留大写属性名),就会导致文档中没有id字段,触发分区键缺失的400错误。可以通过特性强制指定序列化后的字段名:
public class PhoneBook { // 用System.Text.Json的特性 [JsonPropertyName("id")] // 如果用Newtonsoft.Json,替换为[JsonProperty("id")] public string Id { get; set; } [JsonPropertyName("name")] public string Name { get; set; } [JsonPropertyName("description")] public string Description { get; set; } }
3. 捕获详细错误信息定位问题
400状态码只是泛型错误,通过捕获CosmosException可以拿到具体错误描述,这是最快定位问题的方式:
try { PhoneBook pb = new() { Id = Guid.NewGuid().ToString(), Name = "hello world" }; await db.GetContainer("phoneBooks").CreateItemAsync(pb, new PartitionKey(pb.Id)); } catch (CosmosException ex) { Console.WriteLine($"错误详情: {ex.Message}, 错误代码: {ex.StatusCode}, 子状态: {ex.SubStatusCode}"); }
比如分区键不匹配、id字段重复、权限问题等,都会在ex.Message里明确说明。
4. 插入代码的分区键参数验证
你当前插入代码中new PartitionKey(pb.Id)是正确的,因为pb.Id对应序列化后的id字段值,只要容器分区键是/id,这个参数就没问题。
关于手动插入成功的说明
数据资源管理器手动输入的文档明确指定了小写的id字段,和容器分区键/id完全匹配,所以能成功插入;而代码中如果出现序列化字段名不匹配、容器分区键配置不符等问题,就会触发400错误。
内容的提问来源于stack exchange,提问作者Stephan Steiner
相关产品推荐
相关产品推荐

