DocumentDB ReplaceDocument 失败

DocumentDB ReplaceDocument Fails

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

"Errors":["The input content is invalid because the required properties - 'id; ' - are missing","The request payload is invalid. Ensure to provide a valid request payload."]

这是一个博客 post 场景,当添加新评论时,我获取文档、添加评论并调用 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);

Post class:

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

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

我做错了什么?

您必须检查 ID = null

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

好的,我明白了。

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

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

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

正如 Hossein 所指出的,您可以修改 class 以将 属性 序列化为 'id'(区分大小写)。

或者,也可以这样做:

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

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

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

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

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

或者你可以告诉 Cosmos 使用 camelCasingWhichIsStandardForJson

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

  }
)