Esempio n. 1
0
        public void WriteDeltaFeedInline_Sets_DeltaLink()
        {
            // Arrange
            IEnumerable           instance  = new object[0];
            ODataDeltaResourceSet deltafeed = new ODataDeltaResourceSet {
                DeltaLink = new Uri("http://deltalink.com/")
            };
            Mock <ODataDeltaFeedSerializer> serializer = new Mock <ODataDeltaFeedSerializer>(_serializerProvider);

            serializer.CallBase = true;
            serializer.Setup(s => s.CreateODataDeltaFeed(instance, _customersType, _writeContext)).Returns(deltafeed);
            var mockWriter = new Mock <ODataWriter>();

            mockWriter.Setup(m => m.WriteStart(deltafeed));
            mockWriter
            .Setup(m => m.WriteEnd())
            .Callback(() =>
            {
                Assert.Equal("http://deltalink.com/", deltafeed.DeltaLink.AbsoluteUri);
            })
            .Verifiable();

            // Act
            serializer.Object.WriteDeltaFeedInline(instance, _customersType, mockWriter.Object, _writeContext);

            // Assert
            mockWriter.Verify();
        }
        public void WriteDerivedEntity()
        {
            this.TestInit(this.GetModel());

            ODataDeltaResourceSet feed          = new ODataDeltaResourceSet();
            ODataResource         derivedEntity = new ODataResource()
            {
                TypeName   = "MyNS.PhysicalProduct",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "Id", Value = new ODataPrimitiveValue(1)
                    },
                    new ODataProperty {
                        Name = "Name", Value = new ODataPrimitiveValue("car")
                    },
                    new ODataProperty {
                        Name = "Material", Value = new ODataPrimitiveValue("gold")
                    },
                },
            };

            ODataJsonLightDeltaWriter writer = new ODataJsonLightDeltaWriter(outputContext, this.GetProducts(), this.GetProductType());

            writer.WriteStart(feed);
            writer.WriteStart(derivedEntity);
            writer.WriteEnd();
            writer.WriteEnd();
            writer.Flush();

            this.TestPayload().Should().Be("{\"@odata.context\":\"http://host/service/$metadata#Products/$delta\",\"value\":[{\"@odata.type\":\"#MyNS.PhysicalProduct\",\"Id\":1,\"Name\":\"car\",\"Material\":\"gold\"}]}");
        }
        public async Task WriteObjectInlineAsync_Sets_DeltaLink()
        {
            // Arrange
            IEnumerable           instance         = new object[0];
            ODataDeltaResourceSet deltaResourceSet = new ODataDeltaResourceSet {
                DeltaLink = new Uri("http://deltalink.com/")
            };
            Mock <IODataSerializerProvider>        serializeProvider = new Mock <IODataSerializerProvider>();
            Mock <ODataDeltaResourceSetSerializer> serializer        = new Mock <ODataDeltaResourceSetSerializer>(serializeProvider.Object);

            serializer.CallBase = true;
            serializer.Setup(s => s.CreateODataDeltaResourceSet(instance, _customersType, _writeContext)).Returns(deltaResourceSet);
            var mockWriter = new Mock <ODataWriter>();

            mockWriter.Setup(m => m.WriteStartAsync(deltaResourceSet));
            mockWriter
            .Setup(m => m.WriteEndAsync())
            .Callback(() =>
            {
                Assert.Equal("http://deltalink.com/", deltaResourceSet.DeltaLink.AbsoluteUri);
            })
            .Returns(Task.CompletedTask)
            .Verifiable();

            // Act
            await serializer.Object.WriteObjectInlineAsync(instance, _customersType, mockWriter.Object, _writeContext);

            // Assert
            mockWriter.Verify();
        }
Esempio n. 4
0
        /// <summary>
        /// Read the delta resource set.
        /// </summary>
        /// <param name="reader">The OData reader.</param>
        /// <param name="itemsStack">The item stack.</param>
        /// <param name="topLevelItem">The top level item.</param>
        private static void ReadDeltaResourceSet(ODataReader reader, Stack <ODataItemWrapper> itemsStack, ref ODataItemWrapper topLevelItem)
        {
            Contract.Assert(reader != null);
            Contract.Assert(itemsStack != null);
            Contract.Assert(ODataReaderState.DeltaResourceSetStart == reader.State);

            ODataDeltaResourceSet deltaResourceSet = (ODataDeltaResourceSet)reader.Item;

            Contract.Assert(deltaResourceSet != null, "Delta ResourceSet should never be null.");

            ODataDeltaResourceSetWrapper deltaResourceSetWrapper = new ODataDeltaResourceSetWrapper(deltaResourceSet);

            if (itemsStack.Count > 0)
            {
                ODataNestedResourceInfoWrapper parentNestedResourceInfo = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                Contract.Assert(parentNestedResourceInfo != null, "this has to be an inner delta resource set. inner delta resource sets always have a nested resource info.");
                Contract.Assert(parentNestedResourceInfo.NestedResourceInfo.IsCollection == true, "Only collection nested properties can contain delta resource set as their child.");
                Contract.Assert(parentNestedResourceInfo.NestedItems.Count == 0, "Each nested property can contain only one delta resource set as its direct child.");
                parentNestedResourceInfo.NestedItems.Add(deltaResourceSetWrapper);
            }
            else
            {
                topLevelItem = deltaResourceSetWrapper;
            }

            itemsStack.Push(deltaResourceSetWrapper);
        }
        public async Task WriteDeltaFeedInlineAsync_Sets_NextPageLink_OnWriteEndAsync()
        {
            // Arrange
            IEnumerable           instance  = new object[0];
            ODataDeltaResourceSet deltafeed = new ODataDeltaResourceSet {
                NextPageLink = new Uri("http://nextlink.com/")
            };
            Mock <ODataSerializerProvider>  serializeProvider = new Mock <ODataSerializerProvider>();
            Mock <ODataDeltaFeedSerializer> serializer        = new Mock <ODataDeltaFeedSerializer>(serializeProvider.Object);

            serializer.CallBase = true;
            serializer.Setup(s => s.CreateODataDeltaFeed(instance, _customersType, _writeContext)).Returns(deltafeed);
            var mockWriter = new Mock <ODataWriter>();

            mockWriter.Setup(m => m.WriteStartAsync(It.Is <ODataDeltaResourceSet>(f => f.NextPageLink == null))).Verifiable();
            mockWriter
            .Setup(m => m.WriteEndAsync())
            .Callback(() =>
            {
                Assert.Equal("http://nextlink.com/", deltafeed.NextPageLink.AbsoluteUri);
            })
            .Returns(Task.CompletedTask)
            .Verifiable();

            // Act
            await serializer.Object.WriteDeltaFeedInlineAsync(instance, _customersType, mockWriter.Object, _writeContext);

            // Assert
            mockWriter.Verify();
        }
        /// <summary>
        /// Create the <see cref="ODataDeltaResourceSet"/> to be written for the given feed instance.
        /// </summary>
        /// <param name="feedInstance">The instance representing the feed being written.</param>
        /// <param name="feedType">The EDM type of the feed being written.</param>
        /// <param name="writeContext">The serializer context.</param>
        /// <returns>The created <see cref="ODataDeltaResourceSet"/> object.</returns>
        public virtual ODataDeltaResourceSet CreateODataDeltaFeed(IEnumerable feedInstance, IEdmCollectionTypeReference feedType,
                                                                  ODataSerializerContext writeContext)
        {
            ODataDeltaResourceSet feed = new ODataDeltaResourceSet();

            if (writeContext.ExpandedResource == null)
            {
                // If we have more OData format specific information apply it now, only if we are the root feed.
                PageResult odataFeedAnnotations = feedInstance as PageResult;
                if (odataFeedAnnotations != null)
                {
                    feed.Count        = odataFeedAnnotations.Count;
                    feed.NextPageLink = odataFeedAnnotations.NextPageLink;
                }
                else if (writeContext.Request != null)
                {
                    feed.NextPageLink = writeContext.InternalRequest.Context.NextLink;
                    feed.DeltaLink    = writeContext.InternalRequest.Context.DeltaLink;

                    long?countValue = writeContext.InternalRequest.Context.TotalCount;
                    if (countValue.HasValue)
                    {
                        feed.Count = countValue.Value;
                    }
                }
            }
            return(feed);
        }
        public void WriteContainedEntityInDeltaFeed()
        {
            this.TestInit(this.GetModel());

            ODataDeltaResourceSet feed           = new ODataDeltaResourceSet();
            ODataResource         containedEntry = new ODataResource()
            {
                TypeName   = "MyNS.ProductDetail",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "Id", Value = new ODataPrimitiveValue(1)
                    },
                    new ODataProperty {
                        Name = "Detail", Value = new ODataPrimitiveValue("made in china")
                    },
                },
            };

            containedEntry.SetSerializationInfo(new ODataResourceSerializationInfo()
            {
                NavigationSourceEntityTypeName = "MyNS.ProductDetail",
                NavigationSourceName           = "Products(1)/Details",
                NavigationSourceKind           = EdmNavigationSourceKind.ContainedEntitySet
            });

            ODataResource containedInContainedEntity = new ODataResource()
            {
                TypeName   = "MyNS.ProductDetailItem",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "ItemId", Value = new ODataPrimitiveValue(1)
                    },
                    new ODataProperty {
                        Name = "Description", Value = new ODataPrimitiveValue("made by HCC")
                    },
                },
            };

            containedInContainedEntity.SetSerializationInfo(new ODataResourceSerializationInfo()
            {
                NavigationSourceEntityTypeName = "MyNS.ProductDetailItem",
                NavigationSourceName           = "Products(1)/Details(1)/Items",
                NavigationSourceKind           = EdmNavigationSourceKind.ContainedEntitySet
            });

            ODataJsonLightDeltaWriter writer = new ODataJsonLightDeltaWriter(outputContext, this.GetProducts(), this.GetProductType());

            writer.WriteStart(feed);
            writer.WriteStart(containedEntry);
            writer.WriteEnd();
            writer.WriteStart(containedInContainedEntity);
            writer.WriteEnd();
            writer.WriteEnd();
            writer.Flush();

            this.TestPayload().Should().Be("{\"@odata.context\":\"http://host/service/$metadata#Products/$delta\",\"value\":[{\"@odata.context\":\"http://host/service/$metadata#Products(1)/Details/$entity\",\"Id\":1,\"Detail\":\"made in china\"},{\"@odata.context\":\"http://host/service/$metadata#Products(1)/Details(1)/Items/$entity\",\"ItemId\":1,\"Description\":\"made by HCC\"}]}");
        }
        public void WriteEntityInDeltaFeedWithSelectExpand()
        {
            this.TestInit(this.GetModel());

            ODataDeltaResourceSet feed = new ODataDeltaResourceSet();

            ODataResource orderEntry = new ODataResource()
            {
                SerializationInfo = new ODataResourceSerializationInfo
                {
                    NavigationSourceEntityTypeName = "Order",
                    NavigationSourceKind           = EdmNavigationSourceKind.EntitySet,
                    NavigationSourceName           = "Orders"
                },
            };

            ODataNestedResourceInfo shippingAddressInfo = new ODataNestedResourceInfo
            {
                Name         = "ShippingAddress",
                IsCollection = false
            };

            ODataResource shippingAddress = new ODataResource
            {
                Properties = new List <ODataProperty>
                {
                    new ODataProperty {
                        Name = "City", Value = "Shanghai"
                    },
                }
            };

            var result = new ODataQueryOptionParser(this.GetModel(), this.GetCustomerType(), this.GetCustomers(), new Dictionary <string, string> {
                { "$expand", "Orders($select=ShippingAddress)" }, { "$select", "ContactName" }
            }).ParseSelectAndExpand();

            ODataUri odataUri = new ODataUri()
            {
                ServiceRoot     = new Uri("http://host/service"),
                SelectAndExpand = result
            };

            var outputContext = CreateJsonLightOutputContext(this.stream, this.GetModel(), false, odataUri);
            ODataJsonLightDeltaWriter writer = new ODataJsonLightDeltaWriter(outputContext, this.GetProducts(), this.GetProductType());

            writer.WriteStart(feed);
            writer.WriteStart(orderEntry);
            writer.WriteStart(shippingAddressInfo);
            writer.WriteStart(shippingAddress);
            writer.WriteEnd();
            writer.WriteEnd();
            writer.WriteEnd();
            writer.WriteEnd();
            writer.Flush();

            this.TestPayload().Should().Be("{\"@odata.context\":\"http://host/service/$metadata#Products(ContactName,Orders(ShippingAddress))/$delta\",\"value\":[{\"@odata.context\":\"http://host/service/$metadata#Orders/$entity\",\"ShippingAddress\":{\"City\":\"Shanghai\"}}]}");
        }
        public void CreateODataDeltaFeed_Sets_NextPageLinkForPageResult()
        {
            // Arrange
            ODataDeltaFeedSerializer serializer = new ODataDeltaFeedSerializer(_serializerProvider);
            Uri        expectedNextLink         = new Uri("http://nextlink.com");
            const long ExpectedCountValue       = 1000;

            var result = new PageResult <Customer>(_customers, expectedNextLink, ExpectedCountValue);

            // Act
            ODataDeltaResourceSet feed = serializer.CreateODataDeltaFeed(result, _customersType, new ODataSerializerContext());

            // Assert
            Assert.Equal(expectedNextLink, feed.NextPageLink);
        }
        public void CreateODataDeltaResourceSet_Sets_CountValueForPageResult()
        {
            // Arrange
            Mock <ODataSerializerProvider>  serializeProvider = new Mock <ODataSerializerProvider>();
            ODataDeltaResourceSetSerializer serializer        = new ODataDeltaResourceSetSerializer(serializeProvider.Object);
            Uri        expectedNextLink   = new Uri("http://nextlink.com");
            const long ExpectedCountValue = 1000;

            var result = new PageResult <Customer>(_customers, expectedNextLink, ExpectedCountValue);

            // Act
            ODataDeltaResourceSet feed = serializer.CreateODataDeltaResourceSet(result, _customersType, new ODataSerializerContext());

            // Assert
            Assert.Equal(ExpectedCountValue, feed.Count);
        }
        private void WriteAnnotationAtEndInDeltaFeed(string expectedPayload, long?count, Uri nextLink, Uri deltaLink)
        {
            Action <ODataWriter> action = (odataWriter) =>
            {
                var feedToWrite = new ODataDeltaResourceSet {
                    Id = new Uri("urn:feedId")
                };
                odataWriter.WriteStart(feedToWrite);
                feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.EndAnnotation", PrimitiveValue1));
                feedToWrite.Count        = count;
                feedToWrite.NextPageLink = nextLink;
                feedToWrite.DeltaLink    = deltaLink;
                odataWriter.WriteEnd();
            };

            WriteDeltaFeedAnnotationsAndValidatePayload(action, EntitySet, expectedPayload);
        }
        public void WriteDeltaFeedInline_Writes_CreateODataFeedOutput()
        {
            // Arrange
            IEnumerable                     instance   = new object[0];
            ODataDeltaResourceSet           deltafeed  = new ODataDeltaResourceSet();
            Mock <ODataDeltaFeedSerializer> serializer = new Mock <ODataDeltaFeedSerializer>(_serializerProvider);

            serializer.CallBase = true;
            serializer.Setup(s => s.CreateODataDeltaFeed(instance, _customersType, _writeContext)).Returns(deltafeed);
            Mock <ODataWriter> writer = new Mock <ODataWriter>();

            writer.Setup(s => s.WriteStart(deltafeed)).Verifiable();

            // Act
            serializer.Object.WriteDeltaFeedInline(instance, _customersType, writer.Object, _writeContext);

            // Assert
            writer.Verify();
        }
        public async Task WriteObjectInlineAsync_Writes_CreateODataFeedOutput()
        {
            // Arrange
            IEnumerable                            instance         = new object[0];
            ODataDeltaResourceSet                  deltaResourceSet = new ODataDeltaResourceSet();
            Mock <ODataSerializerProvider>         provider         = new Mock <ODataSerializerProvider>();
            Mock <ODataDeltaResourceSetSerializer> serializer       = new Mock <ODataDeltaResourceSetSerializer>(provider.Object);

            serializer.CallBase = true;
            serializer.Setup(s => s.CreateODataDeltaResourceSet(instance, _customersType, _writeContext)).Returns(deltaResourceSet);
            Mock <ODataWriter> writer = new Mock <ODataWriter>();

            writer.Setup(s => s.WriteStartAsync(deltaResourceSet)).Verifiable();

            // Act
            await serializer.Object.WriteObjectInlineAsync(instance, _customersType, writer.Object, _writeContext);

            // Assert
            writer.Verify();
        }
Esempio n. 14
0
        public static void WriteDeltaFeed(ODataDeltaWriter deltaWriter, List <ODataItem> items, bool?countOption, Uri newDeltaLink)
        {
            var deltaFeed = new ODataDeltaResourceSet
            {
                DeltaLink = newDeltaLink
            };

            if (countOption == true)
            {
                deltaFeed.Count = items.Cast <object>().Count();
            }
            deltaWriter.WriteStart(deltaFeed);

            foreach (ODataItem item in items)
            {
                var entry            = item as ODataResource;
                var deletedEntry     = item as ODataDeltaDeletedEntry;
                var deltaLink        = item as ODataDeltaLink;
                var deltaDeletedLink = item as ODataDeltaDeletedLink;

                if (entry != null)
                {
                    deltaWriter.WriteStart(entry);
                    deltaWriter.WriteEnd();
                }
                else if (deletedEntry != null)
                {
                    deltaWriter.WriteDeltaDeletedEntry(deletedEntry);
                }
                else if (deltaLink != null)
                {
                    deltaWriter.WriteDeltaLink(deltaLink);
                }
                else if (deltaDeletedLink != null)
                {
                    deltaWriter.WriteDeltaDeletedLink(deltaDeletedLink);
                }
            }
            deltaWriter.WriteEnd();
        }
Esempio n. 15
0
        public void RequestDeltaLink()
        {
            var customersSet = Model.FindDeclaredEntitySet("Customers");
            var customerType = customersSet.EntityType();

            ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings()
            {
                BaseUri = ServiceBaseUri
            };

            foreach (var mimeType in deltaMimeTypes)
            {
                var requestMessage = new HttpWebRequestMessage(new Uri(ServiceBaseUri.AbsoluteUri + "$delta", UriKind.Absolute));
                requestMessage.SetHeader("Accept", mimeType);
                var responseMessage = requestMessage.GetResponse();
                Assert.Equal(200, responseMessage.StatusCode);

                if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
                {
                    using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, Model))
                    {
                        var deltaReader = messageReader.CreateODataDeltaReader(customersSet, customerType);

                        while (deltaReader.Read())
                        {
                            if (deltaReader.State == ODataDeltaReaderState.DeltaResourceEnd)
                            {
                                ODataResource entry = deltaReader.Item as ODataResource;
                            }
                            else if (deltaReader.State == ODataDeltaReaderState.DeltaResourceSetEnd)
                            {
                                ODataDeltaResourceSet feed = deltaReader.Item as ODataDeltaResourceSet;
                            }
                        }
                        Assert.Equal(ODataDeltaReaderState.Completed, deltaReader.State);
                    }
                }
            }
        }
        /// <summary>
        /// Create the <see cref="ODataDeltaResourceSet"/> to be written for the given feed instance.
        /// </summary>
        /// <param name="feedInstance">The instance representing the feed being written.</param>
        /// <param name="feedType">The EDM type of the feed being written.</param>
        /// <param name="writeContext">The serializer context.</param>
        /// <returns>The created <see cref="ODataDeltaResourceSet"/> object.</returns>
        public virtual ODataDeltaResourceSet CreateODataDeltaFeed(IEnumerable feedInstance, IEdmCollectionTypeReference feedType,
                                                                  ODataSerializerContext writeContext)
        {
            ODataDeltaResourceSet feed = new ODataDeltaResourceSet();

            if (writeContext.ExpandedResource == null)
            {
                // If we have more OData format specific information apply it now, only if we are the root feed.
                PageResult odataFeedAnnotations = feedInstance as PageResult;
                if (odataFeedAnnotations != null)
                {
                    feed.Count        = odataFeedAnnotations.Count;
                    feed.NextPageLink = odataFeedAnnotations.NextPageLink;
                }
                else if (writeContext.Request != null)
                {
                    feed.NextPageLink = writeContext.Request.ODataProperties().NextLink;
                    feed.DeltaLink    = writeContext.Request.ODataProperties().DeltaLink;

                    long?countValue = writeContext.Request.ODataProperties().TotalCount;
                    if (countValue.HasValue)
                    {
                        feed.Count = countValue.Value;
                    }
                }
            }
            else
            {
                // nested feed
                ITruncatedCollection truncatedCollection = feedInstance as ITruncatedCollection;
                if (truncatedCollection != null && truncatedCollection.IsTruncated)
                {
                    feed.NextPageLink = GetNestedNextPageLink(writeContext, truncatedCollection.PageSize);
                }
            }
            return(feed);
        }
Esempio n. 17
0
 /// <summary>
 /// Asynchronously start writing a delta resource set.
 /// </summary>
 /// <param name="deltaResourceSet">Delta resource set/collection to write.</param>
 /// <returns>A task instance that represents the asynchronous write operation.</returns>
 public override Task WriteStartAsync(ODataDeltaResourceSet deltaResourceSet)
 {
     return(this.resourceWriter.WriteStartAsync(deltaResourceSet));
 }
 /// <summary>
 /// Initializes a new instance of <see cref="ODataDeltaResourceSetWrapper"/>.
 /// </summary>
 /// <param name="deltaResourceSet">The wrapped delta resource set item.</param>
 public ODataDeltaResourceSetWrapper(ODataDeltaResourceSet deltaResourceSet)
 {
     DeltaResourceSet = deltaResourceSet;
     DeltaItems       = new List <ODataItemWrapper>();
 }
        public override void Process(IODataRequestMessage requestMessage, IODataResponseMessage responseMessage)
        {
            var token = HttpUtility.ParseQueryString(RequestUri.Query).Get("$token");

            if (string.IsNullOrEmpty(token))
            {
                deltaToken = "common";
            }
            else
            {
                deltaToken = token;
            }

            if (deltaToken == "common")
            {
                originalUri = new Uri(ServiceConstants.ServiceBaseUri, "Customers?$expand=Orders");
                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    var entitySet  = this.DataSource.Model.FindDeclaredEntitySet("Customers");
                    var entityType = entitySet.EntityType();
                    ODataDeltaWriter deltaWriter = messageWriter.CreateODataDeltaWriter(entitySet, entityType);

                    var deltaFeed  = new ODataDeltaResourceSet();
                    var deltaEntry = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name + "(1)"),
                        Properties = new[] { new ODataProperty {
                                                 Name = "FirstName", Value = "GGGG"
                                             } }
                    };
                    var deletedLink = new ODataDeltaDeletedLink(
                        new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name + "(1)"), new Uri(ServiceConstants.ServiceBaseUri, "Orders(8)"), "Orders");
                    var addedLink = new ODataDeltaLink(
                        new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name + "(1)"), new Uri(ServiceConstants.ServiceBaseUri, "Orders(7)"), "Orders");
                    var navigationEntry = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, "Orders(100)"),
                        TypeName   = "Microsoft.Test.OData.Services.ODataWCFService.Order",
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "OrderID", Value = 100
                            },
                            new ODataProperty {
                                Name = "OrderDate", Value = new DateTimeOffset(DateTime.Now)
                            }
                        }
                    };
                    navigationEntry.SetSerializationInfo(new ODataResourceSerializationInfo
                    {
                        NavigationSourceEntityTypeName = "Microsoft.Test.OData.Services.ODataWCFService.Order",
                        NavigationSourceKind           = EdmNavigationSourceKind.EntitySet,
                        NavigationSourceName           = "Orders"
                    });

                    var deletedEntry = new ODataDeltaDeletedEntry(
                        new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name + "(2)").AbsoluteUri, DeltaDeletedEntryReason.Deleted);

                    deltaFeed.DeltaLink = new Uri(ServiceConstants.ServiceBaseUri, "$delta?$token=common");

                    deltaWriter.WriteStart(deltaFeed);
                    deltaWriter.WriteStart(deltaEntry);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteDeltaDeletedLink(deletedLink);
                    deltaWriter.WriteDeltaLink(addedLink);
                    deltaWriter.WriteStart(navigationEntry);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteDeltaDeletedEntry(deletedEntry);
                    deltaWriter.WriteEnd();
                }
            }
            else if (deltaToken == "containment")
            {
                originalUri = new Uri(ServiceConstants.ServiceBaseUri, "Accounts(103)/MyPaymentInstruments?$expand=BillingStatements");
                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    var accountsSet = this.DataSource.Model.FindDeclaredEntitySet("Accounts");
                    var accountType = accountsSet.EntityType();
                    var myPisNav    = accountType.FindProperty("MyPaymentInstruments") as IEdmNavigationProperty;
                    var piSet       = accountsSet.FindNavigationTarget(myPisNav);
                    var piType      = piSet.EntityType();
                    ODataDeltaWriter deltaWriter = messageWriter.CreateODataDeltaWriter(piSet as IEdmContainedEntitySet, piType);

                    var deltaFeed  = new ODataDeltaResourceSet();
                    var deltaEntry = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, "Accounts(103)/MyPaymentInstruments(103901)"),
                        Properties = new[] { new ODataProperty {
                                                 Name = "FriendlyName", Value = "GGGG"
                                             } }
                    };

                    var deletedEntry = new ODataDeltaDeletedEntry(
                        new Uri(ServiceConstants.ServiceBaseUri, "Accounts(103)/MyPaymentInstruments(103901)/BillingStatements(103901001)").AbsoluteUri,
                        DeltaDeletedEntryReason.Deleted);
                    deletedEntry.SetSerializationInfo(new ODataDeltaSerializationInfo()
                    {
                        NavigationSourceName = "Accounts(103)/MyPaymentInstruments(103901)/BillingStatements"
                    });

                    var deletedLink = new ODataDeltaDeletedLink(
                        new Uri(ServiceConstants.ServiceBaseUri, "Accounts(103)/MyPaymentInstruments(103901)"),
                        new Uri(ServiceConstants.ServiceBaseUri, "Accounts(103)/MyPaymentInstruments(103901)/BillingStatements(103901001)"),
                        "BillingStatements");

                    var navigationEntry = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, "Accounts(103)/MyPaymentInstruments(103901)/BillingStatements(103901005)"),
                        TypeName   = "Microsoft.Test.OData.Services.ODataWCFService.Statement",
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "TransactionType", Value = "OnlinePurchase"
                            },
                            new ODataProperty {
                                Name = "TransactionDescription", Value = "unknown purchase"
                            },
                            new ODataProperty {
                                Name = "Amount", Value = 32.1
                            }
                        }
                    };
                    navigationEntry.SetSerializationInfo(new ODataResourceSerializationInfo
                    {
                        NavigationSourceEntityTypeName = "Microsoft.Test.OData.Services.ODataWCFService.Statement",
                        NavigationSourceKind           = EdmNavigationSourceKind.ContainedEntitySet,
                        NavigationSourceName           = "Accounts(103)/MyPaymentInstruments(103901)/BillingStatements"
                    });

                    var addedLink = new ODataDeltaLink(
                        new Uri(ServiceConstants.ServiceBaseUri, "Accounts(103)/MyPaymentInstruments(103901)"),
                        new Uri(ServiceConstants.ServiceBaseUri, "Accounts(103)/MyPaymentInstruments(103901)/BillingStatements(103901005)"),
                        "BillingStatements");

                    deltaWriter.WriteStart(deltaFeed);
                    deltaWriter.WriteStart(deltaEntry);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteDeltaDeletedEntry(deletedEntry);
                    deltaWriter.WriteDeltaDeletedLink(deletedLink);
                    deltaWriter.WriteStart(navigationEntry);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteDeltaLink(addedLink);
                    deltaWriter.WriteEnd();
                }
            }
            else if (deltaToken == "derived")
            {
                originalUri = new Uri(ServiceConstants.ServiceBaseUri, "People?$expand=Microsoft.Test.OData.Services.ODataWCFService.Customer/Orders");
                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    var peopleSet  = this.DataSource.Model.FindDeclaredEntitySet("People");
                    var personType = peopleSet.EntityType();
                    ODataDeltaWriter deltaWriter = messageWriter.CreateODataDeltaWriter(peopleSet, personType);

                    var deltaFeed  = new ODataDeltaResourceSet();
                    var deltaEntry = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, "People(1)"),
                        TypeName   = "Microsoft.Test.OData.Services.ODataWCFService.Customer",
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "City", Value = "GGGG"
                            }
                        }
                    };

                    var addedLink = new ODataDeltaLink(
                        new Uri(ServiceConstants.ServiceBaseUri, "People(1)"), new Uri(ServiceConstants.ServiceBaseUri, "Orders(7)"), "Orders");

                    var deletedEntry = new ODataDeltaDeletedEntry(
                        new Uri(ServiceConstants.ServiceBaseUri, "People(2)").AbsoluteUri,
                        DeltaDeletedEntryReason.Changed);

                    var deletedLink = new ODataDeltaDeletedLink(
                        new Uri(ServiceConstants.ServiceBaseUri, "People(1)"),
                        new Uri(ServiceConstants.ServiceBaseUri, "Orders(8)"),
                        "Orders");

                    var navigationEntry = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, "Orders(100)"),
                        TypeName   = "Microsoft.Test.OData.Services.ODataWCFService.Order",
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "OrderID", Value = 100
                            },
                            new ODataProperty {
                                Name = "OrderDate", Value = new DateTimeOffset(DateTime.Now)
                            }
                        }
                    };
                    navigationEntry.SetSerializationInfo(new ODataResourceSerializationInfo
                    {
                        NavigationSourceEntityTypeName = "Microsoft.Test.OData.Services.ODataWCFService.Order",
                        NavigationSourceKind           = EdmNavigationSourceKind.EntitySet,
                        NavigationSourceName           = "Orders"
                    });

                    deltaWriter.WriteStart(deltaFeed);
                    deltaWriter.WriteStart(deltaEntry);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteDeltaDeletedLink(deletedLink);
                    deltaWriter.WriteDeltaLink(addedLink);
                    deltaWriter.WriteStart(navigationEntry);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteDeltaDeletedEntry(deletedEntry);
                    deltaWriter.WriteEnd();
                }
            }
            else if (deltaToken == "expanded")
            {
                originalUri = new Uri(ServiceConstants.ServiceBaseUri, "Customers?$expand=Orders");
                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    var customerSet              = this.DataSource.Model.FindDeclaredEntitySet("Customers");
                    var orderSet                 = this.DataSource.Model.FindDeclaredEntitySet("Orders");
                    var peopleSet                = this.DataSource.Model.FindDeclaredEntitySet("People");
                    var customerType             = customerSet.EntityType();
                    ODataDeltaWriter deltaWriter = messageWriter.CreateODataDeltaWriter(customerSet, customerType);

                    // Delta feed and entry
                    var deltaFeed = new ODataDeltaResourceSet
                    {
                        DeltaLink = new Uri(ServiceConstants.ServiceBaseUri, "$delta?$token=expanded")
                    };
                    var deltaEntry = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, customerSet.Name + "(1)"),
                        Properties = new[] { new ODataProperty {
                                                 Name = "FirstName", Value = "GGGG"
                                             } }
                    };
                    var nestedResourceInfoIndeltaEntry = new ODataNestedResourceInfo
                    {
                        Name         = "HomeAddress",
                        IsCollection = false,
                    };
                    var nestedResource = new ODataResource
                    {
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "Street", Value = "Zixing Road"
                            },
                            new ODataProperty {
                                Name = "City", Value = "Shanghai"
                            },
                            new ODataProperty {
                                Name = "PostalCode", Value = "200001"
                            },
                        }
                    };

                    var nestedResourceInfoInExpanded = new ODataNestedResourceInfo
                    {
                        Name         = "InfoFromCustomer",
                        IsCollection = false,
                    };
                    var nestedResourceInExpanded = new ODataResource
                    {
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "CustomerMessage", Value = "XXL"
                            },
                        }
                    };

                    // Expanded feed
                    var navigationLink = new ODataNestedResourceInfo()
                    {
                        Name         = "Orders",
                        IsCollection = true,
                    };
                    var expandedFeed  = new ODataResourceSet();
                    var expandedEntry = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, orderSet.Name + "(8)"),
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "OrderDate", Value = new DateTimeOffset(2011, 3, 4, 16, 03, 57, TimeSpan.FromHours(-8))
                            },
                            new ODataProperty {
                                Name = "OrderID", Value = 8
                            },
                            new ODataProperty {
                                Name = "OrderShelfLifes", Value = new ODataCollectionValue {
                                    Items = new object[] { new TimeSpan(1) }
                                }
                            },
                            new ODataProperty {
                                Name = "ShelfLife", Value = new TimeSpan(1)
                            },
                            new ODataProperty {
                                Name = "ShipDate", Value = new Date(2014, 8, 12)
                            },
                            new ODataProperty {
                                Name = "ShipTime", Value = new TimeOfDay(6, 5, 30, 0)
                            },
                        }
                    };

                    // Expanded entry
                    var navigationLinkSingle = new ODataNestedResourceInfo()
                    {
                        Name         = "Parent",
                        IsCollection = false,
                    };
                    var expandedEntrySingle = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, peopleSet.Name + "(2)"),
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "FirstName", Value = "Jill"
                            },
                            new ODataProperty {
                                Name = "LastName", Value = "Jones"
                            },
                            new ODataProperty {
                                Name = "Numbers", Value = new ODataCollectionValue()
                            },
                            new ODataProperty {
                                Name = "Emails", Value = new ODataCollectionValue()
                            },
                            new ODataProperty {
                                Name = "PersonID", Value = 2
                            },
                            new ODataProperty {
                                Name = "Home", Value = GeographyPoint.Create(15.0, 161.8)
                            },
                        }
                    };

                    // Delta feed and entry
                    deltaWriter.WriteStart(deltaFeed);
                    deltaWriter.WriteStart(deltaEntry);
                    deltaWriter.WriteStart(nestedResourceInfoIndeltaEntry);
                    deltaWriter.WriteStart(nestedResource);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteEnd();

                    // Expanded feed
                    deltaWriter.WriteStart(navigationLink);
                    deltaWriter.WriteStart(expandedFeed);
                    deltaWriter.WriteStart(expandedEntry);
                    deltaWriter.WriteStart(nestedResourceInfoInExpanded);
                    deltaWriter.WriteStart(nestedResourceInExpanded);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteEnd();

                    // Expanded entry
                    deltaWriter.WriteStart(navigationLinkSingle);
                    deltaWriter.WriteStart(expandedEntrySingle);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteEnd();

                    // Delta feed and entry
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteEnd();
                }
            }
            else if (deltaToken == "projection")
            {
                originalUri = new Uri(ServiceConstants.ServiceBaseUri, "Customers?$select=PersonID,FirstName,LastName&$expand=Orders($select=OrderID,OrderDate)");
                using (var messageWriter = this.CreateMessageWriter(responseMessage))
                {
                    var entitySet  = this.DataSource.Model.FindDeclaredEntitySet("Customers");
                    var entityType = entitySet.EntityType();
                    ODataDeltaWriter deltaWriter = messageWriter.CreateODataDeltaWriter(entitySet, entityType);

                    var deltaFeed   = new ODataDeltaResourceSet();
                    var deltaEntry1 = new ODataResource
                    {
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "PersonID", Value = 1
                            },
                            new ODataProperty {
                                Name = "FirstName", Value = "FFFF"
                            },
                            new ODataProperty {
                                Name = "LastName", Value = "LLLL"
                            },
                            new ODataProperty {
                                Name = "City", Value = "Beijing"
                            }
                        }
                    };
                    var deletedLink = new ODataDeltaDeletedLink(
                        new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name + "(1)"), new Uri(ServiceConstants.ServiceBaseUri, "Orders(8)"), "Orders");
                    var addedLink = new ODataDeltaLink(
                        new Uri(ServiceConstants.ServiceBaseUri, entitySet.Name + "(1)"), new Uri(ServiceConstants.ServiceBaseUri, "Orders(7)"), "Orders");
                    var navigationEntry = new ODataResource
                    {
                        Id         = new Uri(ServiceConstants.ServiceBaseUri, "Orders(100)"),
                        TypeName   = "Microsoft.Test.OData.Services.ODataWCFService.Order",
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "OrderID", Value = 100
                            },
                            new ODataProperty {
                                Name = "OrderDate", Value = new DateTimeOffset(DateTime.Now)
                            }
                        }
                    };
                    navigationEntry.SetSerializationInfo(new ODataResourceSerializationInfo
                    {
                        NavigationSourceEntityTypeName = "Microsoft.Test.OData.Services.ODataWCFService.Order",
                        NavigationSourceKind           = EdmNavigationSourceKind.EntitySet,
                        NavigationSourceName           = "Orders"
                    });

                    var deletedOrderEntry = new ODataDeltaDeletedEntry(
                        new Uri(ServiceConstants.ServiceBaseUri, "Orders(20)").AbsoluteUri, DeltaDeletedEntryReason.Deleted);
                    deletedOrderEntry.SetSerializationInfo(new ODataDeltaSerializationInfo()
                    {
                        NavigationSourceName = "Orders"
                    });

                    var deltaEntry2 = new ODataResource
                    {
                        Properties = new[]
                        {
                            new ODataProperty {
                                Name = "PersonID", Value = 2
                            },
                            new ODataProperty {
                                Name = "FirstName", Value = "AAAA"
                            },
                        }
                    };

                    deltaWriter.WriteStart(deltaFeed);
                    deltaWriter.WriteStart(deltaEntry1);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteDeltaDeletedLink(deletedLink);
                    deltaWriter.WriteDeltaLink(addedLink);
                    deltaWriter.WriteStart(navigationEntry);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteDeltaDeletedEntry(deletedOrderEntry);
                    deltaWriter.WriteStart(deltaEntry2);
                    deltaWriter.WriteEnd();
                    deltaWriter.WriteEnd();
                }
            }
        }
Esempio n. 20
0
        private static void ReadCollectionItem(ODataReader reader, Stack <ODataItemBase> itemsStack, ref ODataItemBase topLevelItem)
        {
            switch (reader.State)
            {
            case ODataReaderState.ResourceStart:
                ODataResource        resource        = (ODataResource)reader.Item;
                ODataResourceWrapper resourceWrapper = null;
                if (resource != null)
                {
                    resourceWrapper = new ODataResourceWrapper(resource);
                }

                if (itemsStack.Count == 0)
                {
                    Contract.Assert(resource != null, "The top-level resource can never be null.");
                    topLevelItem = resourceWrapper;
                }
                else
                {
                    ODataItemBase           parentItem        = itemsStack.Peek();
                    ODataResourceSetWrapper parentResourceSet = parentItem as ODataResourceSetWrapper;
                    if (parentResourceSet != null)
                    {
                        parentResourceSet.Resources.Add(resourceWrapper);
                    }
                    else
                    {
                        ODataNestedResourceInfoWrapper parentNestedResource = parentItem as ODataNestedResourceInfoWrapper;

                        if (parentNestedResource != null)
                        {
                            Contract.Assert(parentNestedResource.NestedResourceInfo.IsCollection == false, "Only singleton nested properties can contain resource as their child.");
                            Contract.Assert(parentNestedResource.NestedItems.Count == 0, "Each nested property can contain only one resource as its direct child.");
                            parentNestedResource.NestedItems.Add(resourceWrapper);
                        }
                        else
                        {
                            ODataDeltaResourceSetWrapper parentDeltaSetResource = (ODataDeltaResourceSetWrapper)parentItem;
                            parentDeltaSetResource.Resources.Add(resourceWrapper);
                        }
                    }
                }

                itemsStack.Push(resourceWrapper);
                break;

            case ODataReaderState.ResourceEnd:
                Contract.Assert(
                    itemsStack.Count > 0 && (reader.Item == null || itemsStack.Peek().Item == reader.Item),
                    "The resource which is ending should be on the top of the items stack.");
                itemsStack.Pop();
                break;

            case ODataReaderState.NestedResourceInfoStart:
                ODataNestedResourceInfo nestedResourceInfo = (ODataNestedResourceInfo)reader.Item;
                Contract.Assert(nestedResourceInfo != null, "nested resource info should never be null.");

                ODataNestedResourceInfoWrapper nestedResourceInfoWrapper = new ODataNestedResourceInfoWrapper(nestedResourceInfo);
                Contract.Assert(itemsStack.Count > 0, "nested resource info can't appear as top-level item.");
                {
                    ODataResourceWrapper parentResource = (ODataResourceWrapper)itemsStack.Peek();
                    parentResource.NestedResourceInfos.Add(nestedResourceInfoWrapper);
                }

                itemsStack.Push(nestedResourceInfoWrapper);
                break;

            case ODataReaderState.NestedResourceInfoEnd:
                Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item,
                                "The nested resource info which is ending should be on the top of the items stack.");
                itemsStack.Pop();
                break;

            case ODataReaderState.ResourceSetStart:
                ODataResourceSet resourceSet = (ODataResourceSet)reader.Item;
                Contract.Assert(resourceSet != null, "ResourceSet should never be null.");

                ODataResourceSetWrapper resourceSetWrapper = new ODataResourceSetWrapper(resourceSet);
                if (itemsStack.Count > 0)
                {
                    ODataNestedResourceInfoWrapper parentNestedResourceInfo = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                    Contract.Assert(parentNestedResourceInfo != null, "this has to be an inner resource set. inner resource sets always have a nested resource info.");
                    Contract.Assert(parentNestedResourceInfo.NestedResourceInfo.IsCollection == true, "Only collection nested properties can contain resource set as their child.");
                    parentNestedResourceInfo.NestedItems.Add(resourceSetWrapper);
                }
                else
                {
                    topLevelItem = resourceSetWrapper;
                }

                itemsStack.Push(resourceSetWrapper);
                break;

            case ODataReaderState.ResourceSetEnd:
                Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The resource set which is ending should be on the top of the items stack.");
                itemsStack.Pop();
                break;

            case ODataReaderState.EntityReferenceLink:
                ODataEntityReferenceLink entityReferenceLink = (ODataEntityReferenceLink)reader.Item;
                Contract.Assert(entityReferenceLink != null, "Entity reference link should never be null.");
                ODataEntityReferenceLinkBase entityReferenceLinkWrapper = new ODataEntityReferenceLinkBase(entityReferenceLink);

                Contract.Assert(itemsStack.Count > 0, "Entity reference link should never be reported as top-level item.");
                {
                    ODataNestedResourceInfoWrapper parentNavigationLink = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                    parentNavigationLink.NestedItems.Add(entityReferenceLinkWrapper);
                }

                break;

            case ODataReaderState.DeltaResourceSetStart:

                ODataDeltaResourceSet deltaResourceSet = (ODataDeltaResourceSet)reader.Item;
                Contract.Assert(deltaResourceSet != null, "ResourceSet should never be null.");

                ODataDeltaResourceSetWrapper deltaResourceSetWrapper = new ODataDeltaResourceSetWrapper(deltaResourceSet);
                if (itemsStack.Count > 0)
                {
                    ODataNestedResourceInfoWrapper parentNestedResourceInfo = (ODataNestedResourceInfoWrapper)itemsStack.Peek();
                    Contract.Assert(parentNestedResourceInfo != null, "this has to be an inner resource set. inner resource sets always have a nested resource info.");
                    Contract.Assert(parentNestedResourceInfo.NestedResourceInfo.IsCollection == true, "Only collection nested properties can contain resource set as their child.");
                    parentNestedResourceInfo.NestedItems.Add(deltaResourceSetWrapper);
                }
                else
                {
                    topLevelItem = deltaResourceSetWrapper;
                }

                itemsStack.Push(deltaResourceSetWrapper);

                break;

            case ODataReaderState.DeltaResourceSetEnd:

                Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The resource set which is ending should be on the top of the items stack.");
                itemsStack.Pop();
                break;

            case ODataReaderState.DeletedResourceStart:
                ODataDeletedResource deletedResource = (ODataDeletedResource)reader.Item;

                if (deletedResource != null)
                {
                    // Note: I expect that deleted resourced will not have other nested resources

                    ODataDeletedResourceWrapper deletedResourceWrapper = new ODataDeletedResourceWrapper(deletedResource);
                    ODataItemBase parentItem = itemsStack.Peek();
                    ODataDeltaResourceSetWrapper parentDeltaSetResource = parentItem as ODataDeltaResourceSetWrapper;

                    if (parentDeltaSetResource != null)
                    {
                        parentDeltaSetResource.DeletedResources.Add(deletedResourceWrapper);
                    }
                }

                break;

            case ODataReaderState.DeletedResourceEnd:
                break;

            default:
                Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state.");
                break;
            }
        }
        public void WriteContainedEntityInDeltaFeedWithSelectExpand()
        {
            this.TestInit(this.GetModel());

            ODataDeltaResourceSet feed = new ODataDeltaResourceSet();

            ODataResource entry = new ODataResource()
            {
                TypeName   = "MyNS.Product",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "Id", Value = new ODataPrimitiveValue(1)
                    },
                    new ODataProperty {
                        Name = "Name", Value = new ODataPrimitiveValue("Car")
                    },
                },
            };

            ODataResource containedEntry = new ODataResource()
            {
                TypeName   = "MyNS.ProductDetail",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "Id", Value = new ODataPrimitiveValue(1)
                    },
                    new ODataProperty {
                        Name = "Detail", Value = new ODataPrimitiveValue("made in china")
                    },
                },
            };

            containedEntry.SetSerializationInfo(new ODataResourceSerializationInfo()
            {
                NavigationSourceEntityTypeName = "MyNS.ProductDetail",
                NavigationSourceName           = "Products(1)/Details",
                NavigationSourceKind           = EdmNavigationSourceKind.ContainedEntitySet
            });


            var result = new ODataQueryOptionParser(this.GetModel(), this.GetProductType(), this.GetProducts(), new Dictionary <string, string> {
                { "$expand", "Details($select=Detail)" }, { "$select", "Name" }
            }).ParseSelectAndExpand();

            ODataUri odataUri = new ODataUri()
            {
                ServiceRoot     = new Uri("http://host/service"),
                SelectAndExpand = result
            };

            var outputContext = CreateJsonLightOutputContext(this.stream, this.GetModel(), false, odataUri);
            ODataJsonLightDeltaWriter writer = new ODataJsonLightDeltaWriter(outputContext, this.GetProducts(), this.GetProductType());

            writer.WriteStart(feed);
            writer.WriteStart(containedEntry);
            writer.WriteEnd();
            writer.WriteStart(entry);
            writer.WriteEnd();
            writer.WriteEnd();
            writer.Flush();

            this.TestPayload().Should().Be("{\"@odata.context\":\"http://host/service/$metadata#Products(Name,Details(Detail))/$delta\",\"value\":[{\"@odata.context\":\"http://host/service/$metadata#Products(1)/Details/$entity\",\"Id\":1,\"Detail\":\"made in china\"},{\"Id\":1,\"Name\":\"Car\"}]}");
        }
 /// <summary>
 /// Initializes a new instance of <see cref="ODataDeltaResourceSetWrapper"/>.
 /// </summary>
 /// <param name="deltaResourceSet">The wrapped delta resource set item.</param>
 public ODataDeltaResourceSetWrapper(ODataDeltaResourceSet deltaResourceSet)
 {
     ResourceBases    = new List <ODataResourceBaseWrapper>();
     DeltaLinks       = new List <ODataDeltaLinkBaseWrapper>();
     DeltaResourceSet = deltaResourceSet;
 }
        private async Task WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataDeltaWriter writer,
                                     ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(feedType != null);

            ODataDeltaResourceSet deltaFeed = CreateODataDeltaFeed(enumerable, feedType.AsCollection(), writeContext);

            if (deltaFeed == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
            }

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = deltaFeed.NextPageLink;

            deltaFeed.NextPageLink = null;

            //Start writing of the Delta Feed
            writer.WriteStart(deltaFeed);

            //Iterate over all the entries present and select the appropriate write method.
            //Write method creates ODataDeltaDeletedEntry / ODataDeltaDeletedLink / ODataDeltaLink or ODataEntry.
            foreach (object entry in enumerable)
            {
                if (entry == null)
                {
                    throw new SerializationException(SRResources.NullElementInCollection);
                }

                IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
                if (edmChangedObject == null)
                {
                    throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
                }

                switch (edmChangedObject.DeltaKind)
                {
                case EdmDeltaEntityKind.DeletedEntry:
                    WriteDeltaDeletedEntry(entry, writer, writeContext);
                    break;

                case EdmDeltaEntityKind.DeletedLinkEntry:
                    WriteDeltaDeletedLink(entry, writer, writeContext);
                    break;

                case EdmDeltaEntityKind.LinkEntry:
                    WriteDeltaLink(entry, writer, writeContext);
                    break;

                case EdmDeltaEntityKind.Entry:
                {
                    IEdmEntityTypeReference elementType     = GetEntityType(feedType);
                    ODataResourceSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(writeContext.Context, elementType) as ODataResourceSerializer;
                    if (entrySerializer == null)
                    {
                        throw new SerializationException(
                                  Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataOutputFormatter).Name));
                    }
                    await entrySerializer.WriteDeltaObjectInline(entry, elementType, writer, writeContext);

                    break;
                }

                default:
                    break;
                }
            }

            // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(feed),
            // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
            // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.
            if (nextPageLink != null)
            {
                deltaFeed.NextPageLink = nextPageLink;
            }

            //End Writing of the Delta Feed
            writer.WriteEnd();
        }
 /// <summary>
 /// Creates a function that takes in an object and generates nextlink uri.
 /// </summary>
 /// <param name="deltaFeed">The resource set describing a collection of structured objects.</param>
 /// <param name="enumerable">>The instance representing the resourceSet being written.</param>
 /// <param name="writeContext">The serializer context.</param>
 /// <returns>The function that generates the NextLink from an object.</returns>
 /// <returns></returns>
 internal static Func <object, Uri> GetNextLinkGenerator(ODataDeltaResourceSet deltaFeed, IEnumerable enumerable, ODataSerializerContext writeContext)
 {
     return(ODataResourceSetSerializer.GetNextLinkGenerator(deltaFeed, enumerable, writeContext));
 }
        private async Task WriteFeedAsync(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer,
                                          ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(feedType != null);

            IEdmStructuredTypeReference elementType = GetResourceType(feedType);

            if (elementType.IsComplex())
            {
                ODataResourceSet resourceSet = new ODataResourceSet()
                {
                    TypeName = feedType.FullName()
                };

                await writer.WriteStartAsync(resourceSet).ConfigureAwait(false);

                ODataResourceSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataResourceSerializer;
                if (entrySerializer == null)
                {
                    throw new SerializationException(
                              Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName()));
                }

                foreach (object entry in enumerable)
                {
                    await entrySerializer.WriteDeltaObjectInlineAsync(entry, elementType, writer, writeContext).ConfigureAwait(false);
                }
            }
            else
            {
                ODataDeltaResourceSet deltaFeed = CreateODataDeltaFeed(enumerable, feedType.AsCollection(), writeContext);
                if (deltaFeed == null)
                {
                    throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
                }

                // save the next page link for later to support JSON odata.streaming.
                Func <object, Uri> nextLinkGenerator = GetNextLinkGenerator(deltaFeed, enumerable, writeContext);
                deltaFeed.NextPageLink = null;

                //Start writing of the Delta Feed
                await writer.WriteStartAsync(deltaFeed).ConfigureAwait(false);

                object lastResource = null;
                //Iterate over all the entries present and select the appropriate write method.
                //Write method creates ODataDeltaDeletedEntry / ODataDeltaDeletedLink / ODataDeltaLink or ODataEntry.
                foreach (object entry in enumerable)
                {
                    if (entry == null)
                    {
                        throw new SerializationException(SRResources.NullElementInCollection);
                    }

                    lastResource = entry;
                    IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
                    if (edmChangedObject == null)
                    {
                        throw new SerializationException(Error.Format(
                                                             SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
                    }

                    switch (edmChangedObject.DeltaKind)
                    {
                    case EdmDeltaEntityKind.DeletedEntry:
                        await WriteDeltaDeletedEntryAsync(entry, writer, writeContext).ConfigureAwait(false);

                        break;

                    case EdmDeltaEntityKind.DeletedLinkEntry:
                        await WriteDeltaDeletedLinkAsync(entry, writer, writeContext).ConfigureAwait(false);

                        break;

                    case EdmDeltaEntityKind.LinkEntry:
                        await WriteDeltaLinkAsync(entry, writer, writeContext).ConfigureAwait(false);

                        break;

                    case EdmDeltaEntityKind.Entry:
                    {
                        ODataResourceSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataResourceSerializer;
                        if (entrySerializer == null)
                        {
                            throw new SerializationException(
                                      Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName()));
                        }
                        await entrySerializer.WriteDeltaObjectInlineAsync(entry, elementType, writer, writeContext)
                        .ConfigureAwait(false);

                        break;
                    }

                    default:
                        break;
                    }
                }

                // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(feed),
                // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
                // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed
                // object before calling WriteEnd(), the next page link will be written at the end, as required for
                // odata.streaming=true support.

                deltaFeed.NextPageLink = nextLinkGenerator(lastResource);
            }

            //End Writing of the Delta Feed
            await writer.WriteEndAsync().ConfigureAwait(false);
        }
Esempio n. 26
0
        private void ValidateTuples(IEnumerable <Tuple <ODataItem, ODataDeltaReaderState, ODataReaderState> > tuples, Uri nextLink = null, Uri feedDeltaLink = null)
        {
            foreach (var tuple in tuples)
            {
                switch (tuple.Item2)
                {
                case ODataDeltaReaderState.DeltaResourceSetStart:
                    ODataDeltaResourceSet deltaFeed = tuple.Item1 as ODataDeltaResourceSet;
                    Assert.NotNull(deltaFeed);
                    if (deltaFeed.Count.HasValue)
                    {
                        Assert.Equal(deltaFeed.Count, feed.Count);
                    }
                    break;

                case ODataDeltaReaderState.DeltaResourceSetEnd:
                    Assert.NotNull(tuple.Item1 as ODataDeltaResourceSet);
                    if (nextLink != null)
                    {
                        Assert.Equal(nextLink, ((ODataDeltaResourceSet)tuple.Item1).NextPageLink);
                    }
                    if (feedDeltaLink != null)
                    {
                        Assert.Equal(feedDeltaLink, ((ODataDeltaResourceSet)tuple.Item1).DeltaLink);
                    }
                    break;

                case ODataDeltaReaderState.DeltaResourceStart:
                    Assert.True(tuple.Item1 is ODataResource);
                    break;

                case ODataDeltaReaderState.DeltaResourceEnd:
                    var deltaResource = tuple.Item1 as ODataResource;
                    Assert.NotNull(deltaResource);
                    Assert.NotNull(deltaResource.Id);
                    if (this.IdEqual(deltaResource.Id, customerUpdated.Id))
                    {
                        Assert.True(PropertiesEqual(deltaResource.Properties, customerUpdated.Properties));
                    }
                    else if (this.IdEqual(deltaResource.Id, order10643.Id))
                    {
                        Assert.True(this.PropertiesEqual(deltaResource.Properties, order10643.Properties));
                    }
                    else
                    {
                        Assert.True(this.PropertiesEqual(deltaResource.Properties, complexPropertyInOrder10643.Properties));
                    }
                    break;

                case ODataDeltaReaderState.DeltaDeletedEntry:
                    var deltaDeletedEntry = tuple.Item1 as ODataDeltaDeletedEntry;
                    Assert.NotNull(deltaDeletedEntry);
                    Assert.True(deltaDeletedEntry.Id.EndsWith(customerDeleted.Id));
                    Assert.Equal(deltaDeletedEntry.Reason, customerDeleted.Reason);
                    break;

                case ODataDeltaReaderState.DeltaLink:
                    var deltaLink = tuple.Item1 as ODataDeltaLink;
                    Assert.NotNull(deltaLink);
                    Assert.True(this.IdEqual(deltaLink.Source, linkToOrder10645.Source));
                    Assert.Equal(deltaLink.Relationship, linkToOrder10645.Relationship);
                    Assert.True(this.IdEqual(deltaLink.Target, linkToOrder10645.Target));
                    break;

                case ODataDeltaReaderState.DeltaDeletedLink:
                    var deltaDeletedLink = tuple.Item1 as ODataDeltaDeletedLink;
                    Assert.NotNull(deltaDeletedLink);
                    Assert.True(this.IdEqual(deltaDeletedLink.Source, linkToOrder10643.Source));
                    Assert.Equal(deltaDeletedLink.Relationship, linkToOrder10643.Relationship);
                    Assert.True(this.IdEqual(deltaDeletedLink.Target, linkToOrder10643.Target));
                    break;

                case ODataDeltaReaderState.NestedResource:
                    switch (tuple.Item3)
                    {
                    case ODataReaderState.Completed:
                    case ODataReaderState.Start:
                        ODataNestedResourceInfo nestedResource = tuple.Item1 as ODataNestedResourceInfo;
                        Assert.NotNull(nestedResource);
                        break;

                    case ODataReaderState.EntityReferenceLink:
                        break;

                    case ODataReaderState.ResourceEnd:
                        ODataResource entry = tuple.Item1 as ODataResource;
                        Assert.NotNull(entry);
                        if (entry.TypeName == "MyNS.Order")
                        {
                            Assert.Equal(10643, entry.Properties.Single(p => p.Name == "Id").Value);
                        }
                        else if (entry.TypeName == "MyNS.Product")
                        {
                            Assert.Equal(1, entry.Properties.Single(p => p.Name == "Id").Value);
                        }
                        else if (entry.TypeName == "MyNS.ProductDetail")
                        {
                            Assert.Equal(1, entry.Properties.Single(p => p.Name == "Id").Value);
                        }
                        else if (entry.TypeName == "MyNS.Address")
                        {
                            Assert.NotNull(entry.Properties.Single(p => p.Name == "Street").Value);
                        }
                        else if (entry.TypeName == "MyNS.City")
                        {
                            Assert.NotNull(entry.Properties.Single(p => p.Name == "CityName").Value);
                        }
                        break;

                    case ODataReaderState.ResourceStart:
                        Assert.NotNull(tuple.Item1 as ODataResource);
                        break;

                    case ODataReaderState.ResourceSetEnd:
                        Assert.NotNull(tuple.Item1 as ODataResourceSet);
                        break;

                    case ODataReaderState.ResourceSetStart:
                        Assert.NotNull(tuple.Item1 as ODataResourceSet);
                        break;

                    case ODataReaderState.NestedResourceInfoEnd:
                        Assert.NotNull(tuple.Item1 as ODataNestedResourceInfo);
                        break;

                    case ODataReaderState.NestedResourceInfoStart:
                        ODataNestedResourceInfo nestedResourceInfo = tuple.Item1 as ODataNestedResourceInfo;
                        Assert.NotNull(nestedResourceInfo);
                        Assert.True(nestedResourceInfo.Name.Equals("Details") || nestedResourceInfo.Name.Equals("Address") || nestedResourceInfo.Name.Equals("City"));
                        break;

                    default:
                        Assert.True(false, "Wrong reader sub state.");
                        break;
                    }
                    break;

                default:
                    Assert.True(false, "Wrong reader state.");
                    break;
                }
            }
        }
 /// <summary>
 /// Asynchronously start writing a delta resource set.
 /// </summary>
 /// <param name="deltaResourceSet">Delta resource set/collection to write.</param>
 /// <returns>A task instance that represents the asynchronous write operation.</returns>
 public override Task WriteStartAsync(ODataDeltaResourceSet deltaResourceSet)
 {
     return(TaskUtils.GetTaskForSynchronousOperation(() => this.resourceWriter.WriteStart(deltaResourceSet)));
 }
 /// <summary>
 /// Start writing a delta resource set.
 /// </summary>
 /// <param name="deltaResourceSet">Delta resource set/collection to write.</param>
 public override void WriteStart(ODataDeltaResourceSet deltaResourceSet)
 {
     this.resourceWriter.WriteStart(deltaResourceSet);
 }
Esempio n. 29
0
 /// <summary>
 /// Initializes a new instance of <see cref="ODataResourceSetWrapper"/>.
 /// </summary>
 /// <param name="item">The wrapped item.</param>
 public ODataDeltaResourceSetWrapper(ODataDeltaResourceSet item)
     : base(item)
 {
     Resources        = new List <ODataResourceWrapper>();
     DeletedResources = new List <ODataDeletedResourceWrapper>();
 }