2

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);
1
  • if gate is of type dynamic then couldn't you just use dynamic API directly: gate.VpApprovalStatus = "Approved" ? Commented Feb 1, 2018 at 14:05

1 Answer 1

1

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:

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

The problem is that the IdeaInitiatedGate is actual a large object with lots of properties not just the one that I listed so I can’t just set these couple of properties I would need to set everything and I don’t know what all of the properties are. And the ones that I am setting may or may not already be present in the Gate object.
I used the basics of what you said, but changed it. See the question for the details exactly what I ended up doing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.