Azure C# Cosmos DB:属性“id”在实际存在时丢失

问题描述 投票:0回答:2

我现在开始使用 CosmosDB,在尝试向数据库中插入一些数据时遇到以下错误:

The input content is invalid because the required properties - 'id; ' - are missing.

我知道我的文档中应该有一个名为

string
id
字段,但即使在我将
[JsonPropertyName("id")]
作为注释添加到对象的
Id
字段后,错误仍然存在。

这是对 CosmosDB 的调用:

var insertionResponse = await container.CreateItemAsync<Article>(
    item: article,
    partitionKey: new PartitionKey(article.Id.ToString())
);

这是

Article
课程:

public partial class Article
{
    [JsonPropertyName("id")]
    public Guid Id { get; set; }
    public Guid CreatedBy { get; set; }
    public DateTime CreatedOn { get; set; }

    public string Title { get; set; }
    public string Body { get; set; }
}

有什么想法为什么会发生这种情况吗?

c# .net azure azure-cosmosdb
2个回答
11
投票

出现此问题的原因是您的代码和 SDK 使用了不同的 JSON 库。您的代码使用

System.Text.Json
,而 SDK 默认使用
Newtonsoft.Json
进行序列化/反序列化。因此,SDK 无法理解
[JsonPropertyName("id")]
属性,并且无法正确序列化文档。

2 可能的解决方案:

  1. 使用

    Newtonsoft.Json
    代替
    System.Text.Json

  2. 配置 SDK 使用

    System.Text.Json
    进行序列化/反序列化。请参阅此链接了解更多详细信息:https://github.com/ealsur/ondotnet-cosmosdb/tree/master/src/episode1/customserializer

更新

不久前我遇到了完全相同的问题,我联系了 Cosmos DB SDK 团队成员之一。他向我指出了我在上面 #2 中分享的链接。他提到的警告是,如果您使用 LINQ 查询,则使用

System.Text.Json
可能不起作用。

其他替代方案(尽管不推荐)是使用 Cosmos DB SDK 版本 4,它默认使用 System.Text.Json。它目前处于预览阶段,根据 SDK 团队的评论,发布日期尚未确定。此外,截至目前,并非 SDK 版本 3 中提供的所有功能在版本 4 中都可用(因此上面有“不推荐”评论)。

更新2

将 System.Text.Json 与 Cosmos DB SDK v3 结合使用有一个更好的实现(比我之前在 #2 中分享的实现更好)。请参阅此链接了解更多详细信息:https://github.com/Azure/azure-cosmos-dotnet-v3/tree/master/Microsoft.Azure.Cosmos.Samples/Usage/SystemTextJson


0
投票

如果您使用 IEntityTypeConfiguration 来配置映射,则只需使用 ToJsonProperty() 方法来定义属性的名称。

另一个技巧是使用 NuGet 包 Humaziner 以驼峰命名法配置属性名称。例如:

public class Article
{
    public string Id { get; set; }
    public Guid Id { get; set; }
    public Guid CreatedBy { get; set; }
    public DateTime CreatedOn { get; set; }

    public string Title { get; set; }
    public string Body { get; set; }
}

public void Configure(EntityTypeBuilder<Article> builder)
{
    builder.ToContainer("articles");
    builder.HasKey(x => x.Id);

    builder
        .Property(x => x.Id)
            .ToJsonProperty(
                nameof(MyDocument.Id).Camelize());
}
© www.soinside.com 2019 - 2024. All rights reserved.