21

In Azure DocumentDB using .NET SDK, I get the following error when calling 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."]

It's a blog post scenario, when a new comment is added, I get the document, add the comment and call ReplaceDocumentAsync. Here's how I do it:

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; }
    ...
}

What am I doing wrong?

Hossein
  • 1,090
  • 1
  • 8
  • 24

5 Answers5

32

OK I figured it out.

Each Document in DocumentDB needs to have an "id" property. If a class does not have one, it will get assigned one and saved into the document. With DocumentDB being case sensitive, my "Id" was just another property and a separate "id" was added and assigned to the document.

I fixed the issue by deleting and recreating all my documents with the following attribute for Id:

[JsonProperty(PropertyName = "id")]
public Guid Id { get; set; }
Hossein
  • 1,090
  • 1
  • 8
  • 24
  • Yup - you must ensure the `id` is populated in the body of the document you are replacing. Just to clarify - an `id` is only auto-generated if it doesn't exist when creating a document. `id` does not get auto-generated on replace (hence the error message). – Andrew Liu Apr 19 '15 at 08:11
  • Is there any way to change the name of that property that DocumentDb expects (as opposed to adding the `JsonProperty` attribute to the object or JObject (for various complex and context-sensitive reasons, I can't easily do that). For example, tell DocumentDb to use "Id" or "DocId" or something like that, instead of "id?" – E-Riz Apr 14 '17 at 18:53
8

alternatively you can tell Cosmos to use camelCasingWhichIsStandardForJson

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

  }
)
Chris DaMour
  • 3,650
  • 28
  • 37
2

As Hossein noted, you can modify your class to serialize a property to 'id' (case sensitive).

Alternatively, one can do something like this:

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

Thus not forcing item to implement it's own 'id' property.

Eric Patrick
  • 2,097
  • 2
  • 20
  • 31
2

This may help someone also. I had this issue recently and realized that Microsoft.Azure.DocumentDB.Core uses 9.0.1 of Newtonsoft.Json. My project was referencing 11.0.2. So my Upserts or Replaces would cause this error or a new document creation. Downgrading to the lowest version of Newtonsoft.Json that I could go 10.0.2 removed the error.

My class had the proper [JsonProperty( PropertyName = "id")] attribute but I am assuming there is a difference in how the serialzation happens with JsonProperty attribute in 11.0.2 as appose to the 9.0.1 Microsoft.Azure.DocumentDB.Core relies on.

FYI: I could only go as low as Newtonsoft.Json 10.0.2, this is due to WindowsAzure.Storage 9.3.1 is reliant on Newtonsoft.Json 10.0.2 version. I hope this helps anyone also facing this issue that has the property jsonproperty attribute but still having issues.

Chris Parker
  • 206
  • 1
  • 9
  • This helped me. I ended up dispensing with the attribute and simply naming my property the lower case 'id'. Can definitely be a disaster sorting out newtonsoft references between different azure libs. – JasonCoder Apr 15 '19 at 15:42
  • I am in a similar situation, whereas I was using .NET Core System.Text.Json and kept getting this error. Switching to Newtonsoft.Json solved it. – malnosna Apr 28 '20 at 19:22
-8

You have to check for ID = null

Document doc = Client.CreateDocumentQuery(Collection.DocumentsLink)
            .Where(d => d.Id != null)
            .Where(d => d.Id == id)
            .AsEnumerable()
            .FirstOrDefault();
​
jdweng
  • 33,250
  • 2
  • 15
  • 20