diff --git a/src/Microsoft.AspNet.OData.Shared/Formatter/Deserialization/ODataResourceDeserializer.cs b/src/Microsoft.AspNet.OData.Shared/Formatter/Deserialization/ODataResourceDeserializer.cs index 893f61db7f..c5c128cb6b 100644 --- a/src/Microsoft.AspNet.OData.Shared/Formatter/Deserialization/ODataResourceDeserializer.cs +++ b/src/Microsoft.AspNet.OData.Shared/Formatter/Deserialization/ODataResourceDeserializer.cs @@ -469,24 +469,24 @@ private ODataResourceWrapper UpdateResourceWrapper(ODataResourceWrapper resource { Contract.Assert(readContext != null); - if (resourceWrapper?.Resource?.Id == null) + if (resourceWrapper?.ResourceBase?.Id == null) { return resourceWrapper; } - IEnumerable keys = CreateKeyProperties(resourceWrapper.Resource.Id, readContext); + IEnumerable keys = CreateKeyProperties(resourceWrapper.ResourceBase.Id, readContext); if (keys == null) { return resourceWrapper; } - if (resourceWrapper.Resource.Properties == null) + if (resourceWrapper.ResourceBase.Properties == null) { - resourceWrapper.Resource.Properties = keys; + resourceWrapper.ResourceBase.Properties = keys; } else { - IDictionary newPropertiesDic = resourceWrapper.Resource.Properties.ToDictionary(p => p.Name, p => p); + IDictionary newPropertiesDic = resourceWrapper.ResourceBase.Properties.ToDictionary(p => p.Name, p => p); foreach (ODataProperty key in keys) { if (!newPropertiesDic.ContainsKey(key.Name)) @@ -495,7 +495,7 @@ private ODataResourceWrapper UpdateResourceWrapper(ODataResourceWrapper resource } } - resourceWrapper.Resource.Properties = newPropertiesDic.Values; + resourceWrapper.ResourceBase.Properties = newPropertiesDic.Values; } return resourceWrapper; diff --git a/src/Microsoft.AspNet.OData/GlobalSuppressions.cs b/src/Microsoft.AspNet.OData/GlobalSuppressions.cs index 2746837e09..72558f284a 100644 --- a/src/Microsoft.AspNet.OData/GlobalSuppressions.cs +++ b/src/Microsoft.AspNet.OData/GlobalSuppressions.cs @@ -65,33 +65,24 @@ [assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Upsert", Scope = "member", Target = "Microsoft.AspNet.OData.DataModificationOperationKind.#Upsert")] [assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Upsert", Scope = "member", Target = "Org.OData.Core.V1.DataModificationOperationKind.#Upsert")] [assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Org.OData.Core.V1")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.AspNet.OData.DeltaSet`1.#TryDeleteObject(System.Collections.Generic.IDictionary`2,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.AspNet.OData.DeltaSet`1.#TryGetObject(System.Collections.Generic.IDictionary`2,System.Object&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.AspNet.OData.EdmChangedObjectCollection.#TryCreateObject(System.Object&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.AspNet.OData.EdmChangedObjectCollection.#TryDeleteObject(System.Collections.Generic.IDictionary`2,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.AspNet.OData.EdmChangedObjectCollection.#TryGetObject(System.Collections.Generic.IDictionary`2,System.Object&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryCreate")] -[assembly: SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryDelete")] -[assembly: SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Scope = "type", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryGet")] -[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.AspNet.OData.DeltaSet`1.#TryCreateObject(System.Object&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryCreate.#Invoke(System.Object&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryCreate.#Invoke(System.Object&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryDelete.#Invoke(System.Collections.Generic.IDictionary`2,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryGet.#Invoke(System.Collections.Generic.IDictionary`2,System.Object&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryGet.#Invoke(System.Collections.Generic.IDictionary`2,System.Object&,System.String&)")] [assembly: SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces", Scope = "type", Target = "Microsoft.AspNet.OData.IDeltaSet")] -[assembly: SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryCreate.#Invoke(System.Object&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler+TryGet.#Invoke(System.Collections.Generic.IDictionary`2,System.Object&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler`1.#TryCreate(!0&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler`1.#TryCreate(!0&,System.String&)")] [assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler`1.#TryGet(System.Collections.Generic.IDictionary`2,!0&,System.String&)")] [assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler`1.#TryDelete(System.Collections.Generic.IDictionary`2,System.String&)")] [assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.PatchMethodHandler`1.#TryGet(System.Collections.Generic.IDictionary`2,!0&,System.String&)")] [assembly: SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces", Scope = "type", Target = "Microsoft.AspNet.OData.IPatchMethodHandler")] [assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "Microsoft.AspNet.OData.Formatter.Serialization.DefaultODataSerializerProvider.#GetODataPayloadSerializerImpl(System.Type,System.Func`1,Microsoft.AspNet.OData.Routing.ODataPath,System.Type)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.EdmPatchMethodHandler.#TryCreate(Microsoft.AspNet.OData.IEdmChangedObject,Microsoft.AspNet.OData.EdmStructuredObject&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Scope = "member", Target = "Microsoft.AspNet.OData.EdmPatchMethodHandler.#TryCreate(Microsoft.AspNet.OData.IEdmChangedObject,Microsoft.AspNet.OData.EdmStructuredObject&,System.String&)")] -[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Scope = "member", Target = "Microsoft.AspNet.OData.EdmPatchMethodHandler.#TryGet(System.Collections.Generic.IDictionary`2,Microsoft.AspNet.OData.EdmStructuredObject&,System.String&)")] [assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.EdmPatchMethodHandler.#TryDelete(System.Collections.Generic.IDictionary`2,System.String&)")] [assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.EdmPatchMethodHandler.#TryGet(System.Collections.Generic.IDictionary`2,Microsoft.AspNet.OData.EdmStructuredObject&,System.String&)")] +[assembly: SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.AspNet.OData.Formatter.ClrTypeCache+EdmTypeCacheItemComparer.#GetHashCode(Microsoft.AspNet.OData.Formatter.ClrTypeCache+EdmTypeCacheItem)")] +[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.EdmPatchMethodHandler.#TryCreate(Microsoft.AspNet.OData.IEdmChangedObject,Microsoft.AspNet.OData.IEdmStructuredObject&,System.String&)")] +[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Scope = "member", Target = "Microsoft.AspNet.OData.EdmPatchMethodHandler.#TryCreate(Microsoft.AspNet.OData.IEdmChangedObject,Microsoft.AspNet.OData.IEdmStructuredObject&,System.String&)")] +[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Scope = "member", Target = "Microsoft.AspNet.OData.EdmPatchMethodHandler.#TryGet(System.Collections.Generic.IDictionary`2,Microsoft.AspNet.OData.IEdmStructuredObject&,System.String&)")] +[assembly: SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Scope = "member", Target = "Microsoft.AspNet.OData.EdmPatchMethodHandler.#TryGet(System.Collections.Generic.IDictionary`2,Microsoft.AspNet.OData.IEdmStructuredObject&,System.String&)")] +[assembly: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.AspNet.OData.EdmDeltaDeletedEntityObject.#_edmType")] +[assembly: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.AspNet.OData.EdmDeltaDeletedLink.#_edmType")] +[assembly: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.AspNet.OData.EdmDeltaEntityObject.#_edmType")] +[assembly: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.AspNet.OData.EdmDeltaLink.#_edmType")] +[assembly: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.AspNet.OData.Formatter.Deserialization.ODataResourceDeserializer.#CreateKeyProperties(System.Uri,Microsoft.AspNet.OData.Formatter.Deserialization.ODataDeserializerContext)")] +[assembly: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.AspNet.OData.Formatter.Deserialization.ODataResourceDeserializer.#CreateResourceWrapper(Microsoft.OData.Edm.IEdmTypeReference,Microsoft.AspNet.OData.Formatter.Deserialization.ODataEntityReferenceLinkBase,Microsoft.AspNet.OData.Formatter.Deserialization.ODataDeserializerContext)")] +[assembly: SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.AspNet.OData.Formatter.Deserialization.ODataResourceDeserializer.#UpdateResourceWrapper(Microsoft.AspNet.OData.Formatter.Deserialization.ODataResourceWrapper,Microsoft.AspNet.OData.Formatter.Deserialization.ODataDeserializerContext)")] diff --git a/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkInsertController.cs b/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkInsertController.cs index f5d0050712..2ce91d15e8 100644 --- a/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkInsertController.cs +++ b/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkInsertController.cs @@ -359,6 +359,11 @@ public ITestActionResult Patch(int key, [FromBody] Delta delta) try { delta.Patch(employee, new EmployeePatchHandler()); + + if(employee.Name == "Bind1") + { + Assert.NotNull(employee.Friends.Single(x => x.Id == 3)); + } } catch (ArgumentException ae) { diff --git a/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkInsertTest.cs b/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkInsertTest.cs index 2fe121d7b4..fd29728e16 100644 --- a/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkInsertTest.cs +++ b/test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkInsertTest.cs @@ -654,6 +654,34 @@ public async Task PatchEmployee_WithDelete() } } + [Fact] + public async Task PatchEmployee_WithODataBind() + { + //Arrange + + string requestUri = this.BaseAddress + "/convention/Employees(1)"; + + var content = @"{ + 'Name':'Bind1' , + 'Friends@odata.bind':['Friends(3)'] + }"; + + var requestForPost = new HttpRequestMessage(new HttpMethod("PATCH"), requestUri); + + StringContent stringContent = new StringContent(content: content, encoding: Encoding.UTF8, mediaType: "application/json"); + requestForPost.Content = stringContent; + + //Act & Assert + using (HttpResponseMessage response = await this.Client.SendAsync(requestForPost)) + { + var json = response.Content.ReadAsStringAsync().Result; + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + + + + } + [Fact] public async Task PatchEmployee_WithAddUpdateAndDelete()