【问题标题】:DocumentDB ReplaceDocument FailsDocumentDB 替换文档失败
【发布时间】:2015-04-19 03:48:19
【问题描述】:

在使用 .NET SDK 的 Azure DocumentDB 中,调用 ReplaceDocumentAsync 时出现以下错误:

“错误”:[“输入内容无效,因为缺少必需的属性 - 'id;' -”,“请求负载无效。确保提供有效的请求负载。”]

这是一个博客文章场景,当添加新评论时,我获取文档,添加评论并调用 ReplaceDocumentAsync。这是我的做法:

string query = "SELECT * FROM Posts p WHERE p.id = 'some guid'";

var post = Client.CreateDocumentQuery<Post>(Collection.DocumentsLink, query)
.AsEnumerable().FirstOrDefault();

post.Comments.Add(comment);

Document doc = Client.CreateDocumentQuery(Collection.DocumentsLink)
            .Where(d => d.Id == id)
            .AsEnumerable()
            .FirstOrDefault();

var document = await Client.ReplaceDocumentAsync(doc.SelfLink, item);

岗位类:

public class Post
{
    public Post()
    {
        Comments = new List<Comment>();
    }

    public Guid Id { get; set; }
    public List<Comment> Comments { get; set; }
    ...
}

我做错了什么?

【问题讨论】:

  • 当分区字段没有值时,我遇到了那个奇怪的异常。

标签: c# .net azure azure-cosmosdb


【解决方案1】:

好的,我想通了。

DocumentDB 中的每个文档都需要有一个“id”属性。如果一个类没有一个,它将被分配一个并保存到文档中。由于 DocumentDB 区分大小写,我的“Id”只是另一个属性,并且添加了一个单独的“id”并将其分配给文档。

我通过删除并重新创建具有以下 Id 属性的所有文档来解决此问题:

[JsonProperty(PropertyName = "id")]
public Guid Id { get; set; }

【讨论】:

  • 是的 - 您必须确保将 id 填充到您要替换的文档的正文中。只是为了澄清 - id 只有在创建文档时不存在时才会自动生成。 id 不会在替换时自动生成(因此出现错误消息)。
  • 有什么方法可以更改 DocumentDb 期望的属性的名称(而不是将 JsonProperty 属性添加到对象或 JObject (出于各种复杂和上下文相关的原因,我可以) t 容易做到这一点)。例如,告诉 DocumentDb 使用“Id”或“DocId”或类似的东西,而不是“id?”
【解决方案2】:

您也可以告诉 Cosmos 使用 camelCasingWhichIsStandardForJson

new CosmosClient(
  connectionstring,
  new CosmosClientOptions(){
    SerializerOptions = new CosmosSerializationOptions(){
      PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
    }

  }
)

【讨论】:

  • 这对我也有帮助,谢谢!不过,看起来 [JsonProperty(PropertyName = "id")] 不起作用的错误。
【解决方案3】:

正如 Hossein 所说,您可以修改您的类以将属性序列化为“id”(区分大小写)。

或者,可以这样做:

dynamic json = JObject.FromObject(item);
json.id = doc.Id;
var document = await Client.ReplaceDocumentAsync(doc.SelfLink, json);

因此不会强制项目实现它自己的“id”属性。

【讨论】:

【解决方案4】:

这也可能对某人有所帮助。我最近遇到了这个问题,并意识到 Microsoft.Azure.DocumentDB.Core 使用了 Newtonsoft.Json 的 9.0.1。我的项目引用了 11.0.2。因此,我的 Upserts 或 Replaces 会导致此错误或创建新文档。降级到最低版本的 Newtonsoft.Json 我可以去 10.0.2 消除了错误。

我的课程具有正确的 [JsonProperty(PropertyName = "id")] 属性,但我假设 11.0.2 中的 JsonProperty 属性与 9.0.1 Microsoft.Azure 的序列化方式有所不同。 DocumentDB.Core 依赖。

仅供参考:我只能降到 Newtonsoft.Json 10.0.2,这是因为 WindowsAzure.Storage 9.3.1 依赖于 Newtonsoft.Json 10.0.2 版本。我希望这可以帮助任何人也面临这个问题,它具有属性 jsonproperty 属性但仍然存在问题。

【讨论】:

  • 这对我有帮助。我最终放弃了该属性,并简单地将我的属性命名为小写“id”。在不同的天蓝色库之间整理 newtonsoft 引用绝对是一场灾难。
  • 我处于类似情况,而我使用的是 .NET Core System.Text.Json 并不断收到此错误。切换到 Newtonsoft.Json 解决了它。
【解决方案5】:

你必须检查 ID = null

Document doc = Client.CreateDocumentQuery(Collection.DocumentsLink)
            .Where(d => d.Id != null)
            .Where(d => d.Id == id)
            .AsEnumerable()
            .FirstOrDefault();
​

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 2016-04-13
    • 2019-05-10
    相关资源
    最近更新 更多