public IActionResult PatchToAddress(int key, Delta <OpenAddress> address) { IList <OpenCustomer> customers = CreateCustomers(); OpenCustomer customer = customers.FirstOrDefault(c => c.CustomerId == key); if (customer == null) { return(NotFound()); } // Verify the origin address OpenAddress origin = customer.Address; VerifyOriginAddress(key, origin); address.Patch(origin); // Do patch // Verify the patched address Assert.Equal("UpdatedStreet", origin.Street); Assert.Equal("City " + key, origin.City); // not changed Assert.NotNull(origin.DynamicProperties); Assert.True(origin.DynamicProperties.Count >= 3); // Including the origin dynamic properties KeyValuePair <string, object> dynamicPropertyBirthDay = origin.DynamicProperties.FirstOrDefault(e => e.Key == "BirthDay"); Assert.Equal(new Date(2016, 1, 29), dynamicPropertyBirthDay.Value); string dynamicPropertyToken = origin.DynamicProperties.FirstOrDefault(e => e.Key == "Token") .Value.ToString().ToUpperInvariant(); switch (dynamicPropertyToken) { case "2E724E81-8462-4BA0-B920-DC87A61C8EA3": // All changed non-dynamic properties: ["Street"] Assert.True(address.GetChangedPropertyNames().Count() == 1); break; case "9B198CA0-9546-4162-A4C0-14EAA255ACA7": // All changed non-dynamic properties: ["Street", "LineB"] Assert.True(address.GetChangedPropertyNames().Count() == 2); Assert.Null(origin.LineA); Assert.NotNull(origin.LineB); Assert.Equal("DescriptionB", origin.LineB.Description); // Fee is not overwritten. Assert.Equal(LineDetails.DefaultValue_Fee, origin.LineB.Fee); break; case "A4D09554-5551-4B36-A1CB-CFBCDB1F4EAD": // All changed non-dynamic properties: ["Street", "LineA", "LineB"] Assert.True(address.GetChangedPropertyNames().Count() == 3); // --- LineA --- Assert.NotNull(origin.LineA); Assert.Equal("DescriptionA", origin.LineA.Description); // LineA.Fee is left as uninitialized. Assert.Equal(LineDetails.UninitializedValue_Fee, origin.LineA.Fee); Assert.NotNull(origin.LineA.PhoneInfo); Assert.Equal("ContactNameA", origin.LineA.PhoneInfo.ContactName); Assert.Equal(7654321, origin.LineA.PhoneInfo.PhoneNumber); // --- LineB --- Assert.NotNull(origin.LineB); Assert.Null(origin.LineB.Description); // LineB.Fee is originally initialized for OpenAddress is created for each customer. Assert.Equal(LineDetails.DefaultValue_Fee, origin.LineB.Fee); Assert.NotNull(origin.LineB.PhoneInfo); Assert.Equal("ContactNameB", origin.LineB.PhoneInfo.ContactName); Assert.Equal(0, origin.LineB.PhoneInfo.PhoneNumber); break; case "2D071BD4-E4FB-4639-8024-BBC173850441": // All changed non-dynamic properties: ["Street", "LineA"] Assert.True(address.GetChangedPropertyNames().Count() == 2); // --- LineA --- Assert.NotNull(origin.LineA); Assert.Equal("LineDetailsWithNewDeepSubNode.", origin.LineA.Description); Assert.Equal(LineDetails.UninitializedValue_Fee, origin.LineA.Fee); Assert.NotNull(origin.LineA.PhoneInfo); Assert.Equal("ContactNameA", origin.LineA.PhoneInfo.ContactName); Assert.Equal(0, origin.LineA.PhoneInfo.PhoneNumber); Assert.NotNull(origin.LineA.PhoneInfo.Spec); Assert.Null(origin.LineA.PhoneInfo.Spec.Make); Assert.Equal(6, origin.LineA.PhoneInfo.Spec.ScreenSize); // --- LineB --- Assert.NotNull(origin.LineB); break; case "250EFC6E-8FA4-4B68-951C-F1E26DE09D1D": Assert.True(origin.DynamicProperties.ContainsKey("Telephone")); // Telephone dynamic property Phone telephone = origin.DynamicProperties["Telephone"] as Phone; Assert.NotNull(telephone); Assert.Equal("ContactNameX", telephone.ContactName); Assert.Equal(13, telephone.PhoneNumber); // Nested complex property Assert.NotNull(telephone.Spec); Assert.Equal(7, telephone.Spec.ScreenSize); break; case "40CEEEDE-031C-45CB-9E44-E6017D635814": Assert.True(origin.DynamicProperties.ContainsKey("Building")); // Building dynamic property Building building = origin.DynamicProperties["Building"] as Building; Assert.NotNull(building); Assert.Equal("BuildingNameY", building.BuildingName); // Nested telephone complex dynamic property Assert.True(building.DynamicProperties.ContainsKey("Telephone")); Phone phone = building.DynamicProperties["Telephone"] as Phone; Assert.NotNull(phone); Assert.Equal("ContactNameZ", phone.ContactName); Assert.Equal(17, phone.PhoneNumber); // Nested complex property Assert.NotNull(phone.Spec); Assert.Equal(5, phone.Spec.ScreenSize); break; case "3CA243CF-460A-4144-B6EB-F5E1180ABDC8": OpenAddress addressInstance = address.GetInstance(); Assert.NotNull(addressInstance); // Complex property Assert.NotNull(addressInstance.LineA); Assert.NotNull(addressInstance.LineA.PhoneInfo); Assert.Equal(7654321, addressInstance.LineA.PhoneInfo.PhoneNumber); object nestedLineAValue; // Fetch LineA property using TryGetNestedPropertyValue Assert.True(address.TryGetNestedPropertyValue("LineA", out nestedLineAValue)); Delta <LineDetails> deltaLineA = nestedLineAValue as Delta <LineDetails>; Assert.NotNull(deltaLineA); // Nested complex property dynamic nestedLineA = deltaLineA; Assert.NotNull(nestedLineA.PhoneInfo); Assert.Equal(7654321, nestedLineA.PhoneInfo.PhoneNumber); break; default: // Error Assert.True(false, "Unexpected token value " + dynamicPropertyToken); break; } return(Updated(customer)); }