Beispiel #1
0
        /// <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;
                }
            }
        }