Reputation: 4454
I have a method that loads a document from Cosmos DB. The document is not strongly type and it cannot be strongly typed. I want to update various properties on the document and then push that document back to CosmosDB.
The problem that I'm having is that the property that I want to update is nested underneath another object and I cannot find documentation on how to navigate down to this sub property and update that.
Here is what I'm currently trying to do.
var project = await Service.GetById(projectId) as Microsoft.Azure.Documents.Document;
var gate = project.GetPropertyValue<dynamic>("IdeaInitiatedGate");
project.SetPropertyValue("IdeaInitiatedGate.VpApprovalStatus", status);
project.SetPropertyValue("IdeaInitiatedGate.VpApprovalComments", comments);
project.SetPropertyValue("IdeaInitiatedGate.VpApprovalOn", DateTime.Now);
project.SetPropertyValue("IdeaInitiatedGate.Status", status == "Approved" ? "Completed" : "Rejected");
if (status == "Approved")
{
project.SetPropertyValue("CharterReview.Status", "Active");
}
var document = await Service.Replace(project);
Service is just wrapper around the actual CosmosDB calls. What is happening with the above code is that new property is being created in the document called "IdeaInitiatedGate.VpApprovalStatus" right at the root of the document. What I want to happen is to update the VpApprovalStatus property of the IdeaInitiatedGate to the new value.
want to update this
{
"IdeaInitiatedGate": {
"VpApprovalStatus": "Approved"
}
}
not create this
{
"IdeaInitiatedGate.VpApprovalStatus": "Approved"
}
The final working solution that I ended up with is below. Basically I use the GetPropertyValue to pull out the root object that I want, which is dynamic and then I change this object and the SetProperty value of the entire dynamic object.
if (!(await Service.GetById(projectId) is Document project)) return null;
var gate = project.GetPropertyValue<dynamic>("IdeaInitiatedGate");
gate.VpApprovalStatus = status;
gate.VpApprovalComments = comments;
gate.VpApprovalOn = DateTime.Now;
gate.Status = status == "Approved" ? "Completed" : "Rejected";
project.SetPropertyValue("IdeaInitiatedGate", gate);
if (status == "Approved")
{
var charterGate = project.GetPropertyValue<dynamic>("CharterReview");
charterGate.Status = "Active";
project.SetPropertyValue("CharterReview", charterGate);
}
var result = await Service.Replace(project);
Upvotes: 2
Views: 10109
Reputation: 24569
We could set IdeaInitiatedGate Property with a JObject
project?.SetPropertyValue("IdeaInitiatedGate", new JObject { { "VpApprovalStatus", status }});
If you want to add the mutilple property for IdeaInitiatedGate. We could do with following way.
project?.SetPropertyValue("IdeaInitiatedGate", new JObject { { "VpApprovalStatus", "Approved" },{ "VpApprovalComments", comments},{ "VpApprovalOn", DateTime.Now }});
The following is the demo code. It works correctly on my side.
var project = (Document)client.CreateDocumentQuery<dynamic>(UriFactory.CreateDocumentCollectionUri(databaseName, collectionName))
.AsEnumerable()
.First();
var gate = project?.GetPropertyValue<dynamic>("IdeaInitiatedGate");
project?.SetPropertyValue("IdeaInitiatedGate", new JObject { { "VpApprovalStatus", "Approved" }});
var document = client.ReplaceDocumentAsync(UriFactory.CreateDocumentUri(databaseName, collectionName, project?.Id), project).Result.Resource;
Check from the Azure Portal:
Upvotes: 1