I'm trying to do a partial update of a subdocument in CosmosDb. My object model is this:
public class PhoneBookCategory
{
public string Id { get; set; }
public string Name { get; set; }
public TestObject SubProp { get; set; }
}
public class TestObject
{
public string StringProp { get; set; }
public int? IntProp { get; set; }
}
Say I want to update the Name property and SubProp, I'd do this
List<PatchOperation> updates = [];
updates.Add(PatchOperation.Add($"/Name", "new name"));
updates.Add(PatchOperation.Add($"/SubProp", new TestObject { StringProp = "hello"}));
database.GetContainer("collectionName").PatchItemAsync<PhoneBookCategory>(item.Id, new PartitionKey(item.Id), patchOperations)
This works fine. Now let's assume I want to only modify SubProp.StringProp
. so, my second PatchOperation would become
updates.Add(PatchOperation.Add($"/SubProp/StringProp", "hello"));
But that just errors out with Bad Request and no useful error message (reason is ()).
I figured 'maybe, it wants a Replace for a subprop instead since in this case we know that SubProp is present, and we just want to change a value on the SubProp document, so I tried this:
updates.Add(PatchOperation.Replace($"/SubProp/StringProp", "hello"));
still, no dice.
So what am I doing wrong? According to Overview, subdocument updates are allowed.
Note that I'm using CosmosClientOptions.SerializerOptions.PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
(in case anyone wonders why I write the patch operations using CamelCase.
Below is a working sample I tested and can display detail error if you still have.
using Microsoft.Azure.Cosmos;
using Newtonsoft.Json;
internal class Program
{
private static async Task Main(string[] args)
{
var endpoint = "xxx";
var key = "xxx";
var itemId = "a835a3c9-fa0a-42f8-b7c6-8d0e93a2e96b";
try
{
var cosmosClient = new CosmosClient(endpoint,key);
var database = cosmosClient.GetDatabase("MyDatabase");
var container = database.GetContainer("MyContainer");
var patchOperations = new[]
{
PatchOperation.Replace("/SubProp/StringProp", "hello")
};
ItemResponse<PhoneBookCategory> itemResponse = await container.PatchItemAsync<PhoneBookCategory>(itemId, new PartitionKey(itemId), patchOperations);
Console.WriteLine($"Item modified with id {itemResponse.Resource.Id}");
}
catch (CosmosException ex)
{
Console.WriteLine($"Cosmos DB Exception with Status {ex.StatusCode} Message: {ex.Message}");
}
}
}
public class PhoneBookCategory
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
public string Name { get; set; }
public TestObject SubProp { get; set; }
}
public class TestObject
{
public string StringProp { get; set; }
public int? IntProp { get; set; }
}