public void WriteContainedEntityInDeltaFeedWithSelectExpand()
        {
            this.TestInit(this.GetModel());

            ODataDeltaFeed feed = new ODataDeltaFeed();

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

            ODataEntry containedEntry = new ODataEntry()
            {
                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 ODataFeedAndEntrySerializationInfo()
            {
                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,Details(Detail))/$delta\",\"value\":[{\"@odata.context\":\"http://host/service/$metadata#Products(1)/Details/$entity\",\"Id\":1,\"Detail\":\"made in china\"},{\"Id\":1,\"Name\":\"Car\"}]}");
        }
 public void ShouldBeAbleToClearTheEntrySerializationInfo()
 {
     ODataEntry entry = new ODataEntry();
     ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set", NavigationSourceEntityTypeName = "ns.base", ExpectedTypeName = "ns.expected" };
     entry.SerializationInfo = serializationInfo;
     entry.SetSerializationInfo(null);
     entry.SerializationInfo.Should().BeNull();
 }
        public void WriteContainedEntityInDeltaFeed()
        {
            this.TestInit(this.GetModel());

            ODataDeltaFeed feed = new ODataDeltaFeed();
            ODataEntry containedEntry = new ODataEntry()
            {
                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 ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceEntityTypeName = "MyNS.ProductDetail",
                NavigationSourceName = "Products(1)/Details",
                NavigationSourceKind = EdmNavigationSourceKind.ContainedEntitySet
            });

            ODataEntry containedInContainedEntity = new ODataEntry()
            {
                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 ODataFeedAndEntrySerializationInfo()
            {
                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\"}]}"); 
        }
Example #4
0
        public void WriteContainedEntityInDeltaFeedWithSelectExpand()
        {
            this.TestInit(this.GetModel());

            ODataDeltaFeed feed = new ODataDeltaFeed();

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

            ODataEntry containedEntry = new ODataEntry()
            {
                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 ODataFeedAndEntrySerializationInfo()
            {
                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,Details(Detail))/$delta\",\"value\":[{\"@odata.context\":\"http://host/service/$metadata#Products(1)/Details/$entity\",\"Id\":1,\"Detail\":\"made in china\"},{\"Id\":1,\"Name\":\"Car\"}]}");
        }
        public void ShouldBeAbleToWriteFeedAndEntryResponseInJsonLightWithoutModel()
        {
            const string expectedPayload =
                "{" +
                    "\"@odata.context\":\"http://www.example.com/$metadata#Customers/NS.VIPCustomer\"," +
                    "\"value\":[" +
                        "{" +
                            "\"Name\":\"Bob\"," +
                            "\"[email protected]\":\"MostRecentOrder\"," +
                            "\"MostRecentOrder\":{\"OrderId\":101}" +
                        "}" +
                    "]" +
                "}";

            var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true };
            writerSettings.SetContentType(ODataFormat.Json);
            writerSettings.ODataUri = new ODataUri() { ServiceRoot = new Uri("http://www.example.com") };

            MemoryStream stream = new MemoryStream();
            IODataResponseMessage responseMessage = new InMemoryMessage { StatusCode = 200, Stream = stream };

            // Write payload
            using (var messageWriter = new ODataMessageWriter(responseMessage, writerSettings))
            {
                var odataWriter = messageWriter.CreateODataFeedWriter();

                // Create customers feed with serializtion info to write odata.metadata.
                var customersFeed = new ODataFeed();
                customersFeed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Customers", NavigationSourceEntityTypeName = "NS.Customer", ExpectedTypeName = "NS.VIPCustomer" });

                // Write customers feed.
                odataWriter.WriteStart(customersFeed);

                // Write VIP customer
                {
                    // Create VIP customer, don't need to pass in serialization info since the writer knows the context from the feed scope.
                    var vipCustomer = new ODataEntry { TypeName = "NS.VIPCustomer" };

                    var customerKey = new ODataProperty { Name = "Name", Value = "Bob" };

                    // Provide serialization info at the property level to compute the edit link.
                    customerKey.SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key });
                    vipCustomer.Properties = new[] { customerKey };

                    // Write customer entry.
                    odataWriter.WriteStart(vipCustomer);

                    // Write expanded most recent order
                    {
                        // No API to set serialization info on ODataNavigationLink since what we are adding on ODataFeed and ODataEntry should be sufficient for the 5.5 release.
                        var navigationLink = new ODataNavigationLink { Name = "MostRecentOrder", IsCollection = false, Url = new Uri("MostRecentOrder", UriKind.Relative) };
                        odataWriter.WriteStart(navigationLink);

                        // Write the most recent customer.
                        {
                            var mostRecentOrder = new ODataEntry { TypeName = "NS.Order" };

                            // Add serialization info so we can computer links.
                            mostRecentOrder.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Orders", NavigationSourceEntityTypeName = "NS.Order", ExpectedTypeName = "NS.Order" });

                            var orderKey = new ODataProperty { Name = "OrderId", Value = 101 };

                            // Provide serialization info at the property level to compute the edit link.
                            orderKey.SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key });
                            mostRecentOrder.Properties = new[] { orderKey };

                            // Write order entry.
                            odataWriter.WriteStart(mostRecentOrder);
                            odataWriter.WriteEnd();
                        }

                        // End navigationLink.
                        odataWriter.WriteEnd();
                    }

                    // End customer entry.
                    odataWriter.WriteEnd();
                }

                // End customers feed.
                odataWriter.WriteEnd();
            }

            stream.Position = 0;
            string payload = (new StreamReader(stream)).ReadToEnd();
            payload.Should().Be(expectedPayload);
        }
Example #6
0
        private string WriteAndVerifyRequestMessage(ODataMessageWriterSettings settings, string mimeType, bool hasModel)
        {
            // create an order entry to POST
            var order = new ODataEntry()
            {
                TypeName = NameSpace + "Order"
            };

            var orderP1 = new ODataProperty {
                Name = "OrderId", Value = -10
            };
            var orderp2 = new ODataProperty {
                Name = "CustomerId", Value = 8212
            };
            var orderp3 = new ODataProperty {
                Name = "Concurrency", Value = null
            };

            order.Properties = new[] { orderP1, orderp2, orderp3 };
            if (!hasModel)
            {
                order.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo()
                {
                    NavigationSourceName = "Order", NavigationSourceEntityTypeName = NameSpace + "Order"
                });
                orderP1.SetSerializationInfo(new ODataPropertySerializationInfo()
                {
                    PropertyKind = ODataPropertyKind.Key
                });
            }

            Dictionary <string, object> expectedOrderObject = WritePayloadHelper.ComputeExpectedFullMetadataEntryObject(WritePayloadHelper.OrderType, "Order(-10)", order, hasModel);

            // write the request message and read using ODL reader
            var requestMessage = new StreamRequestMessage(new MemoryStream(), new Uri(this.ServiceUri + "Order"), "POST");

            requestMessage.SetHeader("Content-Type", mimeType);
            string result = string.Empty;

            using (var messageWriter = this.CreateODataMessageWriter(requestMessage, settings, hasModel))
            {
                var odataWriter = this.CreateODataEntryWriter(messageWriter, WritePayloadHelper.OrderSet, WritePayloadHelper.OrderType, hasModel);
                odataWriter.WriteStart(order);
                odataWriter.WriteEnd();

                Stream stream = requestMessage.GetStream();
                result = WritePayloadHelper.ReadStreamContent(stream);
                if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    var readerSetting = new ODataMessageReaderSettings()
                    {
                        BaseUri = this.ServiceUri
                    };
                    ODataMessageReader messageReader = new ODataMessageReader(requestMessage, readerSetting, WritePayloadHelper.Model);
                    ODataReader        reader        = messageReader.CreateODataEntryReader(WritePayloadHelper.OrderSet, WritePayloadHelper.OrderType);
                    bool verifyEntryCalled           = false;
                    while (reader.Read())
                    {
                        if (reader.State == ODataReaderState.EntryEnd)
                        {
                            ODataEntry entry = reader.Item as ODataEntry;
                            Assert.AreEqual(3, entry.Properties.Count(), "entry.Properties.Count");
                            verifyEntryCalled = true;
                        }
                    }

                    Assert.AreEqual(ODataReaderState.Completed, reader.State);
                    Assert.IsTrue(verifyEntryCalled, "verifyEntryCalled");
                }
            }

            // For Json light, verify the resulting metadata is as expected
            if (mimeType != MimeTypes.ApplicationAtomXml)
            {
                JavaScriptSerializer        jScriptSerializer = new JavaScriptSerializer();
                Dictionary <string, object> resultObject      = jScriptSerializer.DeserializeObject(result) as Dictionary <string, object>;

                // AutoComputePayloadMetadataInJson has no effect on request message metadata
                Assert.AreEqual(this.ServiceUri + "$metadata#Order/$entity", resultObject.Single(e => e.Key == JsonLightConstants.ODataContextAnnotationName).Value);
                resultObject.Remove(JsonLightConstants.ODataContextAnnotationName);

                foreach (var pair in resultObject)
                {
                    Assert.IsFalse(pair.Key.Contains("odata.") || pair.Key.StartsWith("#"));
                }
            }

            return(result);
        }
Example #7
0
        public static void FeedWriteReadNormal()
        {
            ODataFeed Feed = new ODataFeed();

            Feed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceName           = "Mails",
                NavigationSourceEntityTypeName = "NS.Mail",
                NavigationSourceKind           = EdmNavigationSourceKind.ContainedEntitySet
            });

            ODataEntry Entry = new ODataEntry()
            {
                Properties = new[]
                {
                    new ODataProperty()
                    {
                        Name = "Id", Value = 2
                    },
                },
                EditLink = new Uri("http://example/Web/Users(3)"),
            };

            Entry.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceName           = "MyLogin",
                NavigationSourceEntityTypeName = "NS.Person",
                NavigationSourceKind           = EdmNavigationSourceKind.ContainedEntitySet
            });

            // Parse the full request Uri
            ODataPath path = new ODataUriParser(
                CraftModel.Model,
                new Uri("http://example.org/svc/"),
                new Uri("http://example.org/svc/MyLogin/Mails")).ParsePath();

            // Alternatively, construct the normal path for the contained entity manually.
            //ODataPath path = new ODataPath(
            //    new ODataPathSegment[]
            //    {
            //        new SingletonSegment(CraftModel.MyLogin), new NavigationPropertySegment(CraftModel.MailBox, CraftModel.MyLogin)
            //    });

            var stream = new MemoryStream();

            var wsetting = new ODataMessageWriterSettings()
            {
                DisableMessageStreamDisposal = true,

                ODataUri = new ODataUri()
                {
                    ServiceRoot = new Uri("http://example.org/svc/"),
                    Path        = path
                }
            };
            IODataResponseMessage msg = new Message()
            {
                Stream = stream,
            };

            var omw    = new ODataMessageWriter(msg, wsetting);
            var writer = omw.CreateODataFeedWriter();

            writer.WriteStart(Feed);
            writer.WriteStart(Entry);
            writer.WriteEnd();
            writer.WriteEnd();

            stream.Seek(0, SeekOrigin.Begin);
            var payload = new StreamReader(stream).ReadToEnd();

            // {"@odata.context":"http://example.org/svc/$metadata#Web/Items","value":[{"@odata.editLink":"http://example/Web/Users(3)","Id":2}]}
            Console.WriteLine(payload);

            //Read
            ODataEntry entry = null;

            stream.Seek(0, SeekOrigin.Begin);
            var rsetting = new ODataMessageReaderSettings();
            var omr      = new ODataMessageReader(msg, rsetting, CraftModel.Model);
            var reader   = omr.CreateODataFeedReader();

            while (reader.Read())
            {
                if (reader.State == ODataReaderState.EntryEnd)
                {
                    entry = (ODataEntry)reader.Item;
                    break;
                }
            }

            //Id=2
            foreach (var prop in entry.Properties)
            {
                Console.WriteLine("{0}={1}", prop.Name, prop.Value);
            }
        }
        public void WriteContainedEntityInDeltaFeed()
        {
            this.TestInit(this.GetModel());

            ODataDeltaFeed feed           = new ODataDeltaFeed();
            ODataEntry     containedEntry = new ODataEntry()
            {
                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 ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceEntityTypeName = "MyNS.ProductDetail",
                NavigationSourceName           = "Products(1)/Details",
                NavigationSourceKind           = EdmNavigationSourceKind.ContainedEntitySet
            });

            ODataEntry containedInContainedEntity = new ODataEntry()
            {
                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 ODataFeedAndEntrySerializationInfo()
            {
                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();

            string payload = this.TestFinish();

            payload.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\"}]}");
        }
Example #9
0
        /// <summary>
        /// Creates the <see cref="ODataEntry"/> to be written while writing this entity.
        /// </summary>
        /// <param name="selectExpandNode">The <see cref="SelectExpandNode"/> describing the response graph.</param>
        /// <param name="entityInstanceContext">The context for the entity instance being written.</param>
        /// <returns>The created <see cref="ODataEntry"/>.</returns>
        public virtual ODataEntry CreateEntry(SelectExpandNode selectExpandNode, EntityInstanceContext entityInstanceContext)
        {
            if (selectExpandNode == null)
            {
                throw Error.ArgumentNull("selectExpandNode");
            }
            if (entityInstanceContext == null)
            {
                throw Error.ArgumentNull("entityInstanceContext");
            }

            string typeName = entityInstanceContext.EntityType.FullName();

            ODataEntry entry = new ODataEntry
            {
                TypeName   = typeName,
                Properties = CreateStructuralPropertyBag(selectExpandNode.SelectedStructuralProperties, entityInstanceContext),
            };

            if (entityInstanceContext.EdmObject is EdmDeltaEntityObject && entityInstanceContext.NavigationSource != null)
            {
                ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo();
                serializationInfo.NavigationSourceName = entityInstanceContext.NavigationSource.Name;
                serializationInfo.NavigationSourceKind = entityInstanceContext.NavigationSource.NavigationSourceKind();
                IEdmEntityType sourceType = entityInstanceContext.NavigationSource.EntityType();
                if (sourceType != null)
                {
                    serializationInfo.NavigationSourceEntityTypeName = sourceType.Name;
                }
                entry.SetSerializationInfo(serializationInfo);
            }

            // Try to add the dynamic properties if the entity type is open.
            if ((entityInstanceContext.EntityType.IsOpen && selectExpandNode.SelectAllDynamicProperties) ||
                (entityInstanceContext.EntityType.IsOpen && selectExpandNode.SelectedDynamicProperties.Any()))
            {
                IEdmTypeReference entityTypeReference =
                    entityInstanceContext.EntityType.ToEdmTypeReference(isNullable: false);
                List <ODataProperty> dynamicProperties = AppendDynamicProperties(entityInstanceContext.EdmObject,
                                                                                 (IEdmStructuredTypeReference)entityTypeReference,
                                                                                 entityInstanceContext.SerializerContext,
                                                                                 entry.Properties.ToList(),
                                                                                 selectExpandNode.SelectedDynamicProperties.ToArray());

                if (dynamicProperties != null)
                {
                    entry.Properties = entry.Properties.Concat(dynamicProperties);
                }
            }

            IEnumerable <ODataAction> actions = CreateODataActions(selectExpandNode.SelectedActions, entityInstanceContext);

            foreach (ODataAction action in actions)
            {
                entry.AddAction(action);
            }

            IEnumerable <ODataFunction> functions = CreateODataFunctions(selectExpandNode.SelectedFunctions, entityInstanceContext);

            foreach (ODataFunction function in functions)
            {
                entry.AddFunction(function);
            }

            IEdmEntityType pathType = GetODataPathType(entityInstanceContext.SerializerContext);

            AddTypeNameAnnotationAsNeeded(entry, pathType, entityInstanceContext.SerializerContext.MetadataLevel);

            if (entityInstanceContext.NavigationSource != null)
            {
                if (!(entityInstanceContext.NavigationSource is IEdmContainedEntitySet))
                {
                    IEdmModel model = entityInstanceContext.SerializerContext.Model;
                    NavigationSourceLinkBuilderAnnotation linkBuilder = model.GetNavigationSourceLinkBuilder(entityInstanceContext.NavigationSource);
                    EntitySelfLinks selfLinks = linkBuilder.BuildEntitySelfLinks(entityInstanceContext, entityInstanceContext.SerializerContext.MetadataLevel);

                    if (selfLinks.IdLink != null)
                    {
                        entry.Id = selfLinks.IdLink;
                    }

                    if (selfLinks.ReadLink != null)
                    {
                        entry.ReadLink = selfLinks.ReadLink;
                    }

                    if (selfLinks.EditLink != null)
                    {
                        entry.EditLink = selfLinks.EditLink;
                    }
                }

                string etag = CreateETag(entityInstanceContext);
                if (etag != null)
                {
                    entry.ETag = etag;
                }
            }

            return(entry);
        }
        public void ShouldBeAbleToWriteFeedAndEntryResponseInJsonLightWithoutModel()
        {
            const string expectedPayload =
                "{" +
                "\"@odata.context\":\"http://www.example.com/$metadata#Customers/NS.VIPCustomer\"," +
                "\"value\":[" +
                "{" +
                "\"Name\":\"Bob\"," +
                "\"[email protected]\":\"MostRecentOrder\"," +
                "\"MostRecentOrder\":{\"OrderId\":101}" +
                "}" +
                "]" +
                "}";

            var writerSettings = new ODataMessageWriterSettings {
                DisableMessageStreamDisposal = true
            };

            writerSettings.SetContentType(ODataFormat.Json);
            writerSettings.ODataUri = new ODataUri()
            {
                ServiceRoot = new Uri("http://www.example.com")
            };

            MemoryStream          stream          = new MemoryStream();
            IODataResponseMessage responseMessage = new InMemoryMessage {
                StatusCode = 200, Stream = stream
            };

            // Write payload
            using (var messageWriter = new ODataMessageWriter(responseMessage, writerSettings))
            {
                var odataWriter = messageWriter.CreateODataFeedWriter();

                // Create customers feed with serializtion info to write odata.metadata.
                var customersFeed = new ODataFeed();
                customersFeed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo {
                    NavigationSourceName = "Customers", NavigationSourceEntityTypeName = "NS.Customer", ExpectedTypeName = "NS.VIPCustomer"
                });

                // Write customers feed.
                odataWriter.WriteStart(customersFeed);

                // Write VIP customer
                {
                    // Create VIP customer, don't need to pass in serialization info since the writer knows the context from the feed scope.
                    var vipCustomer = new ODataEntry {
                        TypeName = "NS.VIPCustomer"
                    };

                    var customerKey = new ODataProperty {
                        Name = "Name", Value = "Bob"
                    };

                    // Provide serialization info at the property level to compute the edit link.
                    customerKey.SetSerializationInfo(new ODataPropertySerializationInfo {
                        PropertyKind = ODataPropertyKind.Key
                    });
                    vipCustomer.Properties = new[] { customerKey };

                    // Write customer entry.
                    odataWriter.WriteStart(vipCustomer);

                    // Write expanded most recent order
                    {
                        // No API to set serialization info on ODataNavigationLink since what we are adding on ODataFeed and ODataEntry should be sufficient for the 5.5 release.
                        var navigationLink = new ODataNavigationLink {
                            Name = "MostRecentOrder", IsCollection = false, Url = new Uri("MostRecentOrder", UriKind.Relative)
                        };
                        odataWriter.WriteStart(navigationLink);

                        // Write the most recent customer.
                        {
                            var mostRecentOrder = new ODataEntry {
                                TypeName = "NS.Order"
                            };

                            // Add serialization info so we can computer links.
                            mostRecentOrder.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo {
                                NavigationSourceName = "Orders", NavigationSourceEntityTypeName = "NS.Order", ExpectedTypeName = "NS.Order"
                            });

                            var orderKey = new ODataProperty {
                                Name = "OrderId", Value = 101
                            };

                            // Provide serialization info at the property level to compute the edit link.
                            orderKey.SetSerializationInfo(new ODataPropertySerializationInfo {
                                PropertyKind = ODataPropertyKind.Key
                            });
                            mostRecentOrder.Properties = new[] { orderKey };

                            // Write order entry.
                            odataWriter.WriteStart(mostRecentOrder);
                            odataWriter.WriteEnd();
                        }

                        // End navigationLink.
                        odataWriter.WriteEnd();
                    }

                    // End customer entry.
                    odataWriter.WriteEnd();
                }

                // End customers feed.
                odataWriter.WriteEnd();
            }

            stream.Position = 0;
            string payload = (new StreamReader(stream)).ReadToEnd();

            payload.Should().Be(expectedPayload);
        }
        private string SerializeEntryInFullMetadataJson(
            bool? useKeyAsSegment, 
            IEdmModel edmModel, 
            IEdmEntityType entityType = null, 
            IEdmEntitySet entitySet = null)
        {
            var settings = new ODataMessageWriterSettings
            {
                AutoComputePayloadMetadataInJson = true,
                UseKeyAsSegment = useKeyAsSegment,
            };

            settings.SetServiceDocumentUri(new Uri("http://example.com/"));

            var outputStream = new MemoryStream();
            var responseMessage = new InMemoryMessage {Stream = outputStream};
            responseMessage.SetHeader("Content-Type", "application/json;odata.metadata=full");
            string output;

            using(var messageWriter = new ODataMessageWriter((IODataResponseMessage)responseMessage, settings, edmModel))
            {
                var entryWriter = messageWriter.CreateODataEntryWriter(entitySet, entityType);
                ODataProperty keyProperty = new ODataProperty() {Name = "Key", Value = "KeyValue"};

                var entry = new ODataEntry {Properties = new[] {keyProperty}, TypeName = "Namespace.Person"};

                if (edmModel == null)
                {
                    keyProperty.SetSerializationInfo(new ODataPropertySerializationInfo
                    {
                        PropertyKind = ODataPropertyKind.Key
                    });

                    entry.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo
                    {
                        NavigationSourceEntityTypeName = "Namespace.Person",
                        NavigationSourceName = "People",
                        ExpectedTypeName = "Namespace.Person"
                    });
                }

                entryWriter.WriteStart(entry);
                entryWriter.WriteEnd();
                entryWriter.Flush();

                outputStream.Seek(0, SeekOrigin.Begin);
                output = new StreamReader(outputStream).ReadToEnd();
            }

            return output;
        }
Example #12
0
        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 ODataDeltaFeed();
                    var deltaEntry = new ODataEntry
                    {
                        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 ODataEntry
                    {
                        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 ODataFeedAndEntrySerializationInfo
                    {
                        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 ODataDeltaFeed();
                    var deltaEntry = new ODataEntry
                    {
                        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 ODataEntry
                    {
                        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 ODataFeedAndEntrySerializationInfo
                    {
                        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 ODataDeltaFeed();
                    var deltaEntry = new ODataEntry
                    {
                        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 ODataEntry
                    {
                        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 ODataFeedAndEntrySerializationInfo
                    {
                        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 == "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 ODataDeltaFeed();
                    var deltaEntry1 = new ODataEntry
                    {
                        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 ODataEntry
                    {
                        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 ODataFeedAndEntrySerializationInfo
                    {
                        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 ODataEntry
                    {
                        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();
                }
            }
        }
 public void ShouldWritePayloadWhenExpandedFeedAndEntryHasSerializationInfo()
 {
     List<ODataItem> itemsToWrite = new List<ODataItem>();
     var entry1 = new ODataEntry();
     entry1.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "MySet", NavigationSourceEntityTypeName = "NS.MyEntityType" });
     itemsToWrite.Add(entry1);
     itemsToWrite.Add(new ODataNavigationLink { Name = "EntitySetReferenceProperty", IsCollection = true });
     var feed = new ODataFeed();
     feed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "MySet", NavigationSourceEntityTypeName = "NS.MyEntityType" });
     itemsToWrite.Add(feed);
     var entry2 = new ODataEntry();
     entry2.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "MySet2", NavigationSourceEntityTypeName = "NS.MyEntityType2" });
     itemsToWrite.Add(entry2);
     const string expectedPayload = "{\"@odata.context\":\"http://odata.org/test/$metadata#MySet/$entity\",\"EntitySetReferenceProperty\":[{}]}";
     this.WriteNestedItemsAndValidatePayload(entitySetFullName: null, derivedEntityTypeFullName: null, nestedItemToWrite: itemsToWrite.ToArray(), expectedPayload: expectedPayload, writingResponse: true);
 }
 public void ShouldWritePayloadWhenFeedAndEntryHasSerializationInfo()
 {
     var feed = new ODataFeed();
     feed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "MySet", NavigationSourceEntityTypeName = "NS.MyEntityType" });
     var entry = new ODataEntry();
     entry.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "MySet2", NavigationSourceEntityTypeName = "NS.MyEntityType2" });
     List<ODataItem> itemsToWrite = new List<ODataItem>() { feed, entry };
     const string expectedPayload = "{\"@odata.context\":\"http://odata.org/test/$metadata#MySet\",\"value\":[{}]}";
     this.WriteNestedItemsAndValidatePayload(entitySetFullName: null, derivedEntityTypeFullName: null, nestedItemToWrite: itemsToWrite.ToArray(), expectedPayload: expectedPayload, writingResponse: true);
 }