/// <summary> /// Deserializes the given <paramref name="deltaResourceSet"/> under the given <paramref name="readContext"/>. /// </summary> /// <param name="deltaResourceSet">The delta resource set to deserialize.</param> /// <param name="readContext">The deserializer context.</param> /// <returns>The deserialized resource set object.</returns> public virtual IEnumerable ReadDeltaResourceSet(ODataDeltaResourceSetWrapper deltaResourceSet, ODataDeserializerContext readContext) { if (deltaResourceSet == null) { throw Error.ArgumentNull(nameof(deltaResourceSet)); } if (readContext == null) { throw Error.ArgumentNull(nameof(readContext)); } // resource foreach (ODataResourceBaseWrapper resourceBaseWrapper in deltaResourceSet.ResourceBases) { ODataResourceWrapper resourceWrapper = resourceBaseWrapper as ODataResourceWrapper; ODataDeletedResourceWrapper deletedResourceWrapper = resourceBaseWrapper as ODataDeletedResourceWrapper; if (resourceWrapper != null) { IEdmModel model = readContext.Model; if (model == null) { throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext); } IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType; if (actualType == null) { throw new ODataException(Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName)); } IEdmTypeReference edmTypeReference = actualType.ToEdmTypeReference(true); ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmTypeReference); if (deserializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, edmTypeReference.FullName())); } // TODO: normal resource yield return(deserializer.ReadInline(resourceWrapper, edmTypeReference, readContext)); } else { // TODO: deleted resource } } // Delta links foreach (ODataDeltaLinkBaseWrapper deltaLinkBaseWrapper in deltaResourceSet.DeltaLinks) { ODataDeltaDeletedLinkWrapper deletedLinkWrapper = deltaLinkBaseWrapper as ODataDeltaDeletedLinkWrapper; if (deletedLinkWrapper != null) { yield return(ReadDeltaDeletedLink(deletedLinkWrapper, readContext)); } else { yield return(ReadDeltaLink((ODataDeltaLinkWrapper)deltaLinkBaseWrapper, readContext)); } } }
public async Task ReadDeltaResourceSetWorksAsExpected() { // Arrange string payload = "{\"@context\":\"http://example.com/$metadata#Customers/$delta\"," + "\"value\":[" + "{" + "\"@removed\":{\"reason\":\"changed\"}," + "\"CustomerID\":1," + "\"Orders@delta\":[" + "{" + "\"@removed\":{\"reason\":\"deleted\"}," + "\"OrderId\":10" + "}," + "{" + "\"@type\":\"#NS.VipOrder\"," + "\"OrderId\":9," + "\"Email\":\"[email protected]\"" + "}" + "]" + "}" + "]" + "}"; IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers"); Assert.NotNull(customers); // Guard // Act Func <ODataMessageReader, Task <ODataReader> > func = mr => mr.CreateODataDeltaResourceSetReaderAsync(customers, customers.EntityType()); ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func, ODataVersion.V401); // Assert Assert.NotNull(item); // --- DeltaResourceSet // |--- DeleteResource (1) // |--- NestedResourceInfo (1-1) // |--- DeltaResourceSet // |--- DelteResource // |--- Normal Resource ODataDeltaResourceSetWrapper deltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(item); ODataResourceBaseWrapper resourceBase = Assert.Single(deltaResourceSet.ResourceBases); ODataDeletedResourceWrapper deletedResource = Assert.IsType <ODataDeletedResourceWrapper>(resourceBase); Assert.Equal(DeltaDeletedEntryReason.Changed, deletedResource.DeletedResource.Reason); ODataNestedResourceInfoWrapper nestedResourceInfo = Assert.Single(deletedResource.NestedResourceInfos); Assert.Equal("Orders", nestedResourceInfo.NestedResourceInfo.Name); Assert.True(nestedResourceInfo.NestedResourceInfo.IsCollection); ODataDeltaResourceSetWrapper ordersDeltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(nestedResourceInfo.NestedResourceSet); Assert.Equal(2, ordersDeltaResourceSet.ResourceBases.Count); ODataDeletedResourceWrapper deletedResource1 = Assert.IsType <ODataDeletedResourceWrapper>(ordersDeltaResourceSet.ResourceBases.ElementAt(0)); Assert.Equal(DeltaDeletedEntryReason.Deleted, deletedResource1.DeletedResource.Reason); ODataResourceWrapper resource2 = Assert.IsType <ODataResourceWrapper>(ordersDeltaResourceSet.ResourceBases.ElementAt(1)); Assert.Equal("NS.VipOrder", resource2.Resource.TypeName); Assert.Collection(resource2.Resource.Properties, p => { Assert.Equal("OrderId", p.Name); Assert.Equal(9, p.Value); }, p => { Assert.Equal("Email", p.Name); Assert.Equal("*****@*****.**", p.Value); }); }
public async Task ReadDeletedLinkInDeltaResourceSetWorksAsExpected() { // Arrange string payload = "{" + "\"@odata.context\":\"http://localhost/$metadata#Customers/$delta\"," + "\"@odata.count\":5," + "\"value\":[" + "{" + "\"@odata.id\":\"Customers(42)\"," + "\"Name\":\"Sammy\"" + "}," + "{" + "\"@odata.context\":\"http://localhost/$metadata#Customers/$deletedLink\"," + "\"source\":\"Customers(39)\"," + "\"relationship\":\"Orders\"," + "\"target\":\"Orders(10643)\"" + "}," + "{" + "\"@odata.context\":\"http://localhost/$metadata#Customers/$link\"," + "\"source\":\"Customers(32)\"," + "\"relationship\":\"Orders\"," + "\"target\":\"Orders(10645)\"" + "}," + "{" + "\"@odata.context\":\"http://localhost/$metadata#Orders/$entity\"," + "\"@odata.id\":\"Orders(10643)\"," + "\"Price\": 82" + "}," + "{" + "\"@odata.context\":\"http://localhost/$metadata#Customers/$deletedEntity\"," + "\"id\":\"Customers(21)\"," + "\"reason\":\"deleted\"" + "}" + "]," + "\"@odata.deltaLink\":\"Customers?$expand=Orders&$deltatoken=8015\"" + "}"; IEdmEntitySet customers = Model.EntityContainer.FindEntitySet("Customers"); Assert.NotNull(customers); // Guard // Act Func <ODataMessageReader, Task <ODataReader> > func = mr => mr.CreateODataDeltaResourceSetReaderAsync(customers, customers.EntityType()); ODataItemWrapper item = await ReadPayloadAsync(payload, Model, func); // Assert Assert.NotNull(item); // --- DeltaResourceSet // |--- Resource (1) // |--- Resource (2) // |--- DeletedResource (1) // | // |--- DeltaDeletedLink // |--- DeltaLink ODataDeltaResourceSetWrapper deltaResourceSet = Assert.IsType <ODataDeltaResourceSetWrapper>(item); // Resources Assert.Equal(3, deltaResourceSet.ResourceBases.Count); Assert.Collection(deltaResourceSet.ResourceBases, e => { ODataResourceWrapper resource1 = Assert.IsType <ODataResourceWrapper>(e); Assert.Equal("Customers(42)", resource1.Resource.Id.OriginalString); Assert.Equal("Sammy", resource1.Resource.Properties.First(p => p.Name == "Name").Value); }, e => { ODataResourceWrapper resource2 = Assert.IsType <ODataResourceWrapper>(e); Assert.Equal("Orders(10643)", resource2.Resource.Id.OriginalString); Assert.Equal(82, resource2.Resource.Properties.First(p => p.Name == "Price").Value); }, e => { ODataDeletedResourceWrapper deletedResource = Assert.IsType <ODataDeletedResourceWrapper>(e); Assert.Equal("Customers(21)", deletedResource.DeletedResource.Id.OriginalString); Assert.Equal(DeltaDeletedEntryReason.Deleted, deletedResource.DeletedResource.Reason); }); // DeltaLinks Assert.Equal(2, deltaResourceSet.DeltaLinks.Count); Assert.Collection(deltaResourceSet.DeltaLinks, e => { ODataDeltaDeletedLinkWrapper deletedLinkWrapper = Assert.IsType <ODataDeltaDeletedLinkWrapper>(e); Assert.Equal("Customers(39)", deletedLinkWrapper.DeltaDeletedLink.Source.OriginalString); Assert.Equal("Orders(10643)", deletedLinkWrapper.DeltaDeletedLink.Target.OriginalString); Assert.Equal("Orders", deletedLinkWrapper.DeltaDeletedLink.Relationship); }, e => { ODataDeltaLinkWrapper linkWrapper = Assert.IsType <ODataDeltaLinkWrapper>(e); Assert.Equal("Customers(32)", linkWrapper.DeltaLink.Source.OriginalString); Assert.Equal("Orders(10645)", linkWrapper.DeltaLink.Target.OriginalString); Assert.Equal("Orders", linkWrapper.DeltaLink.Relationship); }); }
/// <summary> /// Deserializes the given <paramref name="deltaResourceSet"/> under the given <paramref name="readContext"/>. /// </summary> /// <param name="deltaResourceSet">The delta resource set to deserialize.</param> /// <param name="elementType">The element type.</param> /// <param name="readContext">The deserializer context.</param> /// <returns>The deserialized resource set object.</returns> public virtual IEnumerable ReadDeltaResourceSet(ODataDeltaResourceSetWrapper deltaResourceSet, IEdmStructuredTypeReference elementType, ODataDeserializerContext readContext) { if (deltaResourceSet == null) { throw Error.ArgumentNull(nameof(deltaResourceSet)); } if (readContext == null) { throw Error.ArgumentNull(nameof(readContext)); } // Delta Items foreach (ODataItemWrapper itemWrapper in deltaResourceSet.DeltaItems) { // Deleted Link ODataDeltaDeletedLinkWrapper deletedLinkWrapper = itemWrapper as ODataDeltaDeletedLinkWrapper; if (deletedLinkWrapper != null) { yield return(ReadDeltaDeletedLink(deletedLinkWrapper, elementType, readContext)); } // Added Link ODataDeltaLinkWrapper deltaLinkWrapper = itemWrapper as ODataDeltaLinkWrapper; if (deltaLinkWrapper != null) { yield return(ReadDeltaLink(deltaLinkWrapper, elementType, readContext)); } // DeletedResource ODataDeletedResourceWrapper deletedResourceWrapper = itemWrapper as ODataDeletedResourceWrapper; if (deletedResourceWrapper != null) { // TODO: deleted resource yield return(null); } // Added resource or updated resource ODataResourceWrapper resourceWrapper = itemWrapper as ODataResourceWrapper; if (resourceWrapper != null) { IEdmModel model = readContext.Model; if (model == null) { throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext); } IEdmStructuredType actualType = model.FindType(resourceWrapper.Resource.TypeName) as IEdmStructuredType; if (actualType == null) { throw new ODataException(Error.Format(SRResources.ResourceTypeNotInModel, resourceWrapper.Resource.TypeName)); } IEdmTypeReference edmTypeReference = actualType.ToEdmTypeReference(true); ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmTypeReference); if (deserializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, edmTypeReference.FullName())); } // TODO: normal resource // yield return deserializer.ReadInline(resourceWrapper, edmTypeReference, readContext); if (readContext.IsDeltaOfT) { Type elementClrType = readContext.Model.GetClrType(elementType); Type deltaType = typeof(Deltas.Delta <>).MakeGenericType(elementClrType); Deltas.IDelta delta = Activator.CreateInstance(deltaType) as Deltas.IDelta; yield return(delta); } else { yield return(new EdmDeltaResourceObject(actualType as IEdmEntityType)); } continue; } } }