繁体   English   中英

.NET 核心 API:从文档中提取的 PartitionKey 与 header 中指定的不匹配

[英].NET Core API: PartitionKey extracted from document doesn't match the one specified in the header

背景:

我刚开始使用 Azure CosmosDB 并尝试使用 Entity Framework CosmosDB 提供程序。 我创建了一个简单的 API 以及 Swagger API 文档,它们将在单个实体上运行。

到目前为止,我已经完成了以下工作:

  1. 配置了一个新的 Cosmos DB 数据库 + 容器
  2. 将 CosmosDB 注册到 Startup.cs 中的服务容器中
  3. 配置了一个我想存储在我的新 Cosmos DB 容器中的实体
  4. 为基本 CRUD 操作准备了 API 个端点

问题:

尝试通过 Swagger 调用我的 POST 端点以在我的数据库中创建新记录时,出现以下错误:

Microsoft.Azure.Cosmos.CosmosException:响应状态代码不表示成功:BadRequest (400); 子状态:1001; ActivityId:fe27e816-173c-433e-8699-e9e49e01b96f; 原因:(消息:{“错误”:[“从文档中提取的 PartitionKey 与标头中指定的不匹配”]}

从以下教程和文档中,我收到此错误的原因并不明显! 任何指向正确方向的指针将不胜感激!

可能有用的片段可以帮助别人诊断我哪里出错了:

将 Cosmos DB 注册到服务容器:

var settings = new CosmosDbOptions();

configuration.GetSection(CosmosDbOptions.SECTION_NAME)
    .Bind(settings);

services.AddDbContext<DatabaseContext>(options => 
    {
        options.UseCosmos(
            accountEndpoint: settings.EndpointUri,
            accountKey: settings.PrimaryKey,
            databaseName: settings.DatabaseName
        );
    });

实体:

public class Client : Entity, IGuidIdentifier, IAggregateRoot
{
    public Client() : base() 
    {
        this.Id = Guid.NewGuid();
        this.ClientId = this.Id.ToString();
    }

    public string ClientId { get; private set; }

    public IrisCode IrisCode { get; private set; }

    public string Name { get; private set; }

    public Office Office { get; private set; }

    public Logo Logo { get; private set; }
}

我的实体的实体框架配置:

public class ClientConfig : IEntityTypeConfiguration<Client>
{
    public void Configure(EntityTypeBuilder<Client> builder)
    {
        builder.ToContainer("Clients");
        builder.HasPartitionKey(x => x.ClientId);

        builder.HasKey(x => x.Id);

        builder.Property(x => x.Name);
        builder.Property(x => x.ClientId);
        builder.OwnsOne(x => x.IrisCode);
        builder.OwnsOne(x => x.Office);
        builder.OwnsOne(x => x.Logo);

        builder.Ignore(x => x.DomainEvents);
    }
}

更新:似乎是以下行导致了错误,但是,这使我在 position 中没有定义我想要的分区键。

builder.HasPartitionKey(x => x.ClientId);

出现此错误(PartitionKey extracted from document doesn't match the one specified in the header)是因为您为 Cosmos DB 集合设置的分区键与您在 EF: ClientId中设置的分区键不同。

请确保您的收藏具有相同的分区键,例如,您可以使用 C# 进行设置,如下所示:

this.Container = await this.Database.CreateContainerIfNotExistsAsync("testContainer", "/clientId");

并将密钥保存在您的文档 object 中,如下所示:

[JsonProperty(PropertyName = "clientId")]
public string ClientId { get; set; }

我也一样。 问题在于属性的骆驼外壳。 使用此代码修复它:

 CosmosSerializationOptions cosmosSerializationOptions = new()
 {
     PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase,
     IgnoreNullValues = true
 };

 cosmosClient = new CosmosClient(
      settings.CosmosDbConnectionString,
      new CosmosClientOptions()
      {
          ConnectionMode = ConnectionMode.Gateway,
          SerializerOptions = cosmosSerializationOptions,
          AllowBulkExecution = true
      });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM