public void ShouldBeAbleToSetTheFeedSerializationInfo()
 {
     ODataFeed feed = new ODataFeed();
     ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set", NavigationSourceEntityTypeName = "ns.base", ExpectedTypeName = "ns.expected" };
     feed.SetSerializationInfo(serializationInfo);
     feed.SerializationInfo.Should().BeSameAs(serializationInfo);
 }
        public void InitTest()
        {
            this.navigationLink = new ODataNavigationLink();

            var entry = new ODataEntry
            {
                TypeName = "ns.DerivedType",
                Properties = new[]
                {
                    new ODataProperty{Name = "Id", Value = 1, SerializationInfo = new ODataPropertySerializationInfo{PropertyKind = ODataPropertyKind.Key}},
                    new ODataProperty{Name = "Name", Value = "Bob", SerializationInfo = new ODataPropertySerializationInfo{PropertyKind = ODataPropertyKind.ETag}}
                }
            };

            var serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set", NavigationSourceEntityTypeName = "ns.BaseType", ExpectedTypeName = "ns.BaseType" };
            var typeContext = ODataFeedAndEntryTypeContext.Create(serializationInfo, null, null, null, EdmCoreModel.Instance, true);
            var metadataContext = new TestMetadataContext();
            var entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, null, metadataContext, SelectedPropertiesNode.EntireSubtree);
            var metadataBuilder = new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, new ODataConventionalUriBuilder(ServiceUri, UrlConvention.CreateWithExplicitValue(false)));
            this.navigationLinkWithFullBuilder = new ODataNavigationLink { Name = "NavProp" };
            this.navigationLinkWithFullBuilder.MetadataBuilder = metadataBuilder;

            this.navigationLinkWithNoOpBuilder = new ODataNavigationLink { Name = "NavProp" };
            this.navigationLinkWithNoOpBuilder.MetadataBuilder = new NoOpEntityMetadataBuilder(entry);

            this.navigationLinkWithNullBuilder = new ODataNavigationLink { Name = "NavProp" };
            this.navigationLinkWithNullBuilder.MetadataBuilder = ODataEntityMetadataBuilder.Null;
        }
Beispiel #3
0
        /// <summary>
        /// Validates the <paramref name="serializationInfo"/> instance.
        /// </summary>
        /// <param name="serializationInfo">The serialization info instance to validate.</param>
        /// <returns>The <paramref name="serializationInfo"/> instance.</returns>
        internal static ODataFeedAndEntrySerializationInfo Validate(ODataFeedAndEntrySerializationInfo serializationInfo)
        {
            if (serializationInfo != null)
            {
                ExceptionUtils.CheckArgumentNotNull(serializationInfo.NavigationSourceName, "serializationInfo.NavigationSourceName");
                ExceptionUtils.CheckArgumentNotNull(serializationInfo.NavigationSourceEntityTypeName, "serializationInfo.NavigationSourceEntityTypeName");
            }

            return(serializationInfo);
        }
        public void ComplexTypeCollectionRoundtripAtomTest()
        {
            ODataComplexValue subject0 = new ODataComplexValue() { TypeName = "NS.Subject", Properties = new[] { new ODataProperty() { Name = "Name", Value = "English" }, new ODataProperty() { Name = "Score", Value = (Int16)98 } } };
            ODataComplexValue subject1 = new ODataComplexValue() { TypeName = "NS.Subject", Properties = new[] { new ODataProperty() { Name = "Name", Value = "Math" }, new ODataProperty() { Name = "Score", Value = (Int16)90 } } };
            ODataCollectionValue complexCollectionValue = new ODataCollectionValue { TypeName = "Collection(NS.Subject)", Items = new[] { subject0, subject1 } };
            ODataFeedAndEntrySerializationInfo info = new ODataFeedAndEntrySerializationInfo() {
                NavigationSourceEntityTypeName = subject0.TypeName,
                NavigationSourceName = "Subjects",
                ExpectedTypeName = subject0.TypeName
            };

            this.VerifyTypeCollectionRoundtrip(complexCollectionValue, "Subjects", info);
        }
        /// <summary>
        /// Creates an instance of <see cref="ODataFeedAndEntryTypeContext"/>.
        /// </summary>
        /// <param name="serializationInfo">The serialization info from the feed or entry instance.</param>
        /// <param name="navigationSource">The navigation source of the feed or entry.</param>
        /// <param name="navigationSourceEntityType">The entity type of the navigation source.</param>
        /// <param name="expectedEntityType">The expected entity type of the feed or entry.</param>
        /// <param name="model">The Edm model instance to use.</param>
        /// <param name="throwIfMissingTypeInfo">If true, throw if any of the set or type name cannot be determined; if false, return null when any of the set or type name cannot determined.</param>
        /// <returns>A new instance of <see cref="ODataFeedAndEntryTypeContext"/>.</returns>
        internal static ODataFeedAndEntryTypeContext Create(ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType navigationSourceEntityType, IEdmEntityType expectedEntityType, IEdmModel model, bool throwIfMissingTypeInfo)
        {
            Debug.Assert(model != null, "model != null");
            if (serializationInfo != null)
            {
                return(new ODataFeedAndEntryTypeContextWithoutModel(serializationInfo));
            }

            if (navigationSource != null && model.IsUserModel())
            {
                Debug.Assert(navigationSourceEntityType != null, "navigationSourceEntityType != null");
                Debug.Assert(expectedEntityType != null, "expectedEntityType != null");
                return(new ODataFeedAndEntryTypeContextWithModel(navigationSource, navigationSourceEntityType, expectedEntityType, model));
            }

            return(new ODataFeedAndEntryTypeContext(throwIfMissingTypeInfo));
        }
        public void InitTest()
        {
            this.testSubject = new TestODataOperation();

            var entry = new ODataEntry
            {
                TypeName = "ns.DerivedType",
                Properties = new[]
                {
                    new ODataProperty{Name = "Id", Value = 1, SerializationInfo = new ODataPropertySerializationInfo{PropertyKind = ODataPropertyKind.Key}},
                    new ODataProperty{Name = "Name", Value = "Bob", SerializationInfo = new ODataPropertySerializationInfo{PropertyKind = ODataPropertyKind.ETag}}
                }
            };

            var serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set", NavigationSourceEntityTypeName = "ns.BaseType", ExpectedTypeName = "ns.BaseType" };
            var typeContext = ODataFeedAndEntryTypeContext.Create(serializationInfo, null, null, null, EdmCoreModel.Instance, true);
            var metadataContext = new TestMetadataContext();
            var entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, null, metadataContext, SelectedPropertiesNode.EntireSubtree);
            var fullMetadataBuilder = new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, new ODataConventionalUriBuilder(ServiceUri, UrlConvention.CreateWithExplicitValue(false)));
            this.operationWithFullBuilder = new TestODataOperation { Metadata = ContextUri};
            this.operationWithFullBuilder.SetMetadataBuilder(fullMetadataBuilder, MetadataDocumentUri);
        }
        static ODataFeedAndEntryTypeContextTests()
        {
            Model = new EdmModel();
            EntitySetElementType = new EdmEntityType("ns", "Customer");
            ExpectedEntityType = new EdmEntityType("ns", "VipCustomer", EntitySetElementType);
            ActualEntityType = new EdmEntityType("ns", "DerivedVipCustomer", ExpectedEntityType);

            EdmEntityContainer defaultContainer = new EdmEntityContainer("ns", "DefaultContainer");
            Model.AddElement(defaultContainer);
            Model.AddVocabularyAnnotation(new EdmAnnotation(defaultContainer, UrlConventionsConstants.ConventionTerm, UrlConventionsConstants.KeyAsSegmentAnnotationValue));

            EntitySet = new EdmEntitySet(defaultContainer, "Customers", EntitySetElementType);
            Model.AddElement(EntitySetElementType);
            Model.AddElement(ExpectedEntityType);
            Model.AddElement(ActualEntityType);
            defaultContainer.AddElement(EntitySet);

            SerializationInfo = new ODataFeedAndEntrySerializationInfo {NavigationSourceName = "MyCustomers", NavigationSourceEntityTypeName = "ns.MyCustomer", ExpectedTypeName = "ns.MyVipCustomer"};
            TypeContextWithoutModel = ODataFeedAndEntryTypeContext.Create(SerializationInfo, navigationSource: null, navigationSourceEntityType: null, expectedEntityType: null, model: Model, throwIfMissingTypeInfo: true);
            TypeContextWithModel = ODataFeedAndEntryTypeContext.Create(/*serializationInfo*/null, EntitySet, EntitySetElementType, ExpectedEntityType, Model, throwIfMissingTypeInfo: true);
            BaseTypeContextThatThrows = ODataFeedAndEntryTypeContext.Create(serializationInfo: null, navigationSource: null, navigationSourceEntityType: null, expectedEntityType: null, model: Model, throwIfMissingTypeInfo: true);
            BaseTypeContextThatWillNotThrow = ODataFeedAndEntryTypeContext.Create(serializationInfo: null, navigationSource: null, navigationSourceEntityType: null, expectedEntityType: null, model: Model, throwIfMissingTypeInfo: false);
        }
        private void WriteEntryAndValidatePayloadWithoutModel(ODataEntry entry, string expectedPayload, bool writingResponse = true, bool setMetadataDocumentUri = true)
        {
            MemoryStream stream = new MemoryStream();
            ODataJsonLightOutputContext outputContext = CreateJsonLightOutputContext(stream, writingResponse, this.userModel, setMetadataDocumentUri ? this.serviceDocumentUri : null);

            ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo
            {
                NavigationSourceName = "MySingleton",
                NavigationSourceEntityTypeName = "NS.Web",
                NavigationSourceKind = EdmNavigationSourceKind.Singleton,
            };

            entry.SerializationInfo = serializationInfo;
            ODataJsonLightWriter writer = new ODataJsonLightWriter(outputContext, /*navigationSource*/ null, /*entityType*/ null, /*writingFeed*/ false);
            WriteEntryAndValidatePayload(entry, stream, writer, expectedPayload);
        }
 /// <summary>
 /// Constructor to create a new feed scope.
 /// </summary>
 /// <param name="feed">The feed for the new scope.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 internal FeedScope(ODataFeed feed, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
     : base(WriterState.Feed, feed, navigationSource, entityType, skipWriting, selectedProperties, odataUri)
 {
     this.serializationInfo = feed.SerializationInfo;
 }
        private void VerifyTypeCollectionRoundtrip(ODataCollectionValue value, string propertyName, ODataFeedAndEntrySerializationInfo info)
        {
            var properties = new[] { new ODataProperty { Name = propertyName, Value = value } };
            var entry = new ODataEntry() { TypeName = "NS.Student", Properties = properties, SerializationInfo = info};
            MemoryStream stream = new MemoryStream();
            using (ODataAtomOutputContext outputContext = new ODataAtomOutputContext(
                ODataFormat.Atom,
                new NonDisposingStream(stream),
                Encoding.UTF8,
                new ODataMessageWriterSettings() { Version = ODataVersion.V4 },
                /*writingResponse*/ true,
                /*synchronous*/ true,
                model,
                /*urlResolver*/ null))
            {
                outputContext.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);
                var atomWriter = new ODataAtomWriter(outputContext, /*entitySet*/ null, /*entityType*/ null, /*writingFeed*/ false);
                atomWriter.WriteStart(entry);
                atomWriter.WriteEnd();

            }

            stream.Position = 0;
            object actualValue = null;

            using (ODataAtomInputContext inputContext = new ODataAtomInputContext(
                ODataFormat.Atom,
                stream,
                Encoding.UTF8,
                new ODataMessageReaderSettings(),
                /*readingResponse*/ true,
                /*synchronous*/ true,
                model,
                /*urlResolver*/ null))
            {
                var atomReader = new ODataAtomReader(inputContext, /*entitySet*/ null, /*entityType*/ null, /*writingFeed*/ false);
                while (atomReader.Read())
                {
                    if (atomReader.State == ODataReaderState.EntryEnd)
                    {
                        ODataEntry entryOut = atomReader.Item as ODataEntry;
                        actualValue = entryOut.Properties.Single(p => p.Name == propertyName).ODataValue;
                    }
                }
            }

            TestUtils.AssertODataValueAreEqual(actualValue as ODataValue, value);
        }
        /// <summary>
        /// Validates the <paramref name="serializationInfo"/> instance.
        /// </summary>
        /// <param name="serializationInfo">The serialization info instance to validate.</param>
        /// <returns>The <paramref name="serializationInfo"/> instance.</returns>
        internal static ODataFeedAndEntrySerializationInfo Validate(ODataFeedAndEntrySerializationInfo serializationInfo)
        {
            if (serializationInfo != null)
            {
                if (serializationInfo.NavigationSourceKind != EdmNavigationSourceKind.UnknownEntitySet)
                {
                    ExceptionUtils.CheckArgumentNotNull(serializationInfo.NavigationSourceName, "serializationInfo.NavigationSourceName");
                }

                ExceptionUtils.CheckArgumentNotNull(serializationInfo.NavigationSourceEntityTypeName, "serializationInfo.NavigationSourceEntityTypeName");
            }

            return serializationInfo;
        }
        private string WriteAndVerifyEmployeeEntry(StreamResponseMessage responseMessage, ODataWriter odataWriter,
                                                bool hasExpectedType, string mimeType)
        {

            ODataEntry employeeEntry = WritePayloadHelper.CreateEmployeeEntry(false);
            ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo()
                {
                    NavigationSourceName = "Person",
                    NavigationSourceEntityTypeName = NameSpace + "Person",
                };

            if (hasExpectedType)
            {
                serializationInfo.ExpectedTypeName = NameSpace + "Employee";
            }

            employeeEntry.SetSerializationInfo(serializationInfo);
            odataWriter.WriteStart(employeeEntry);

            var employeeNavigation1 = new ODataNavigationLink()
            {
                Name = "PersonMetadata",
                IsCollection = true,
                Url = new Uri("Person(-3)/" + NameSpace + "Employee" + "/PersonMetadata", UriKind.Relative)
            };
            odataWriter.WriteStart(employeeNavigation1);
            odataWriter.WriteEnd();

            var employeeNavigation2 = new ODataNavigationLink()
            {
                Name = "Manager",
                IsCollection = false,
                Url = new Uri("Person(-3)/" + NameSpace + "Employee" + "/Manager", UriKind.Relative)
            };
            odataWriter.WriteStart(employeeNavigation2);
            odataWriter.WriteEnd();

            // Finish writing employeeEntry.
            odataWriter.WriteEnd();

            // Some very basic verification for the payload.
            bool verifyEntryCalled = false;
            bool verifyNavigationCalled = false;

            Action<ODataEntry> verifyEntry = (entry) =>
            {
                Assert.IsTrue(entry.EditLink.AbsoluteUri.Contains("Person"), "entry.EditLink");
                verifyEntryCalled = true;
            };
            Action<ODataNavigationLink> verifyNavigation = (navigation) =>
            {
                Assert.IsTrue(navigation.Name == "PersonMetadata" || navigation.Name == "Manager", "navigation.Name");
                verifyNavigationCalled = true;
            };

            Stream stream = responseMessage.GetStream();
            if (!mimeType.Contains(MimeTypes.ODataParameterNoMetadata))
            {
                stream.Seek(0, SeekOrigin.Begin);
                WritePayloadHelper.ReadAndVerifyFeedEntryMessage(false, responseMessage, WritePayloadHelper.PersonSet, WritePayloadHelper.PersonType, null,
                                                   verifyEntry, verifyNavigation);
                Assert.IsTrue(verifyEntryCalled && verifyNavigationCalled,
                              "Verification action not called.");
            }

            return WritePayloadHelper.ReadStreamContent(stream);
        }
        public void PrimitiveTypeCollectionRoundtripAtomTest()
        {
            ODataCollectionValue primitiveCollectionValue = new ODataCollectionValue {TypeName = "Collection(Edm.String)", Items = new[]{"Basketball", "Swimming"}};
            ODataFeedAndEntrySerializationInfo info = new ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceEntityTypeName = "Edm.String",
                NavigationSourceName = "Hobbies",
                ExpectedTypeName = "Edm.String"
            };

            this.VerifyTypeCollectionRoundtrip(primitiveCollectionValue, "Hobbies", info);
        }
        public void PayloadOrderTest()
        {
            ODataFeedAndEntrySerializationInfo infoMyType = new ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceEntityTypeName = "MyType",
                NavigationSourceName = "MySet",
                ExpectedTypeName = "MyType"
            };

            ODataFeedAndEntrySerializationInfo infoAllInType = new ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceEntityTypeName = "TestModel.AllInType",
                NavigationSourceName = "MySet",
                ExpectedTypeName = "TestModel.AllInType"
            };

            IEdmModel model = BuildPayloadOrderTestModel();

            IEnumerable<PayloadOrderTestCase> testCases = new []
            {
                new PayloadOrderTestCase
                {
                    DebugDescription = "TypeName at the beginning, nothing else",
                    Entry = new ODataEntry() { TypeName = "MyType", SerializationInfo = infoMyType }
                        .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <category term=\"#MyType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"/>",
                        "{0}  <id />",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "TypeName at the beginning, changes at the end - the one from the beginning is used (also for validation).",
                    Entry = new ODataEntry() {
                            MediaResource = new ODataStreamReferenceValue(),
                            Properties = new []
                            {
                                new ODataProperty { Name = "ID", Value = 42 },
                                new ODataProperty { Name = "Name", Value = "foo" },
                            },
                            SerializationInfo = infoMyType
                        }
                        .WithAnnotation(new WriteEntryCallbacksAnnotation 
                            {
                                BeforeWriteStartCallback = (entry) => { entry.TypeName = "TestModel.AllInType"; },
                                BeforeWriteEndCallback = (entry) => { entry.TypeName = "NonExistingType"; }
                            })
                        .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Model = model,
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <category term=\"#TestModel.AllInType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"/>",
                        "{0}  <id />",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "   <properties xmlns=\"http://docs.oasis-open.org/odata/ns/metadata\">",
                        "       <ID p3:type=\"Edm.Int32\" xmlns:p3=\"http://docs.oasis-open.org/odata/ns/metadata\" xmlns=\"http://docs.oasis-open.org/odata/ns/data\">42</ID>",
                        "       <Name xmlns=\"http://docs.oasis-open.org/odata/ns/data\">foo</Name>",
                        "   </properties>",   
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "Just ETag at the beginning, changed at the end - the one from the beginning should be used.",
                    Entry = new ODataEntry() { SerializationInfo = infoMyType }
                        .WithAnnotation(new WriteEntryCallbacksAnnotation 
                            {
                                BeforeWriteStartCallback = (entry) => { entry.ETag = "\"etag1\""; },
                                BeforeWriteEndCallback = (entry) => { entry.ETag = "\"etag2\""; }
                            })
                        .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry p1:etag=\"&quot;etag1&quot;\" xmlns:p1=\"http://docs.oasis-open.org/odata/ns/metadata\" xmlns=\"http://www.w3.org/2005/Atom\">",
                        "{0}  <id />",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "No TypeName at the beginning, nothing else - should not write the category",
                    Entry = new ODataEntry() { TypeName = null, SerializationInfo = infoMyType }
                        .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "{0}  <id />",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "TypeName and ID at the beginning",
                    Entry = new ODataEntry() { TypeName = "MyType", Id = new Uri("http://odata.org/MyId"), SerializationInfo = infoMyType }
                        .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <id>urn:MyId</id>",
                        "  <category term=\"#MyType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"/>",
                        "{0}  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "TypeName and ID at the end",
                    Entry = new ODataEntry() { TypeName = "MyType", SerializationInfo = infoMyType }
                        .WithAnnotation(new WriteEntryCallbacksAnnotation { 
                            BeforeWriteStartCallback = (entry) => entry.Id = new Uri("http://odata.org/MyId"),
                            BeforeWriteEndCallback = (entry) => entry.Id = new Uri("http://odata.org/MyId") })
                        .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <category term=\"#MyType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"/>",
                        "{0}  <id>urn:MyId</id>",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "TypeName, Self and Edit link at the beginning, Id at the end",
                    Entry = new ODataEntry() { TypeName = "MyType", ReadLink = ObjectModelUtils.DefaultEntryReadLink, EditLink = new Uri("http://odata.org/editlink"), SerializationInfo = infoMyType }
                        .WithAnnotation(new WriteEntryCallbacksAnnotation { 
                            BeforeWriteStartCallback = (entry) => entry.Id = null,
                            BeforeWriteEndCallback = (entry) => entry.Id = new Uri("http://odata.org/MyId") })
                        .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <category term=\"#MyType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"/>",
                        "  <link rel=\"edit\" href=\"http://odata.org/editlink\" />",
                        "  <link rel=\"self\" href=\"" + ObjectModelUtils.DefaultEntryReadLink.OriginalString + "\" />",
                        "{0}  <id>urn:MyId</id>",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "Everything at the beginning",
                    Entry = new ODataEntry() { TypeName = "MyType", Id = new Uri("http://odata.org/MyId"), ReadLink = ObjectModelUtils.DefaultEntryReadLink, EditLink = new Uri("http://odata.org/editlink"), SerializationInfo = infoMyType }
                        .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <id>urn:MyId</id>",
                        "  <category term=\"#MyType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"/>",
                        "  <link rel=\"edit\" href=\"http://odata.org/editlink\" />",
                        "  <link rel=\"self\" href=\"" + ObjectModelUtils.DefaultEntryReadLink.OriginalString + "\" />",
                        "{0}  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "Everything at the end",
                    Entry = new ODataEntry() { TypeName = "MyType", Id = new Uri("http://odata.org/MyId"), SerializationInfo = infoMyType  }
                        .WithAnnotation(new WriteEntryCallbacksAnnotation {
                            BeforeWriteStartCallback = (entry) => { entry.Id = null; entry.ReadLink = null; entry.EditLink = null; },
                            BeforeWriteEndCallback = (entry) => { entry.Id = new Uri("http://odata.org/MyId"); entry.ReadLink = ObjectModelUtils.DefaultEntryReadLink; entry.EditLink = new Uri("http://odata.org/editlink"); }})
                        .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <category term=\"#MyType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"/>",
                        "{0}  <id>urn:MyId</id>",
                        "  <link rel=\"edit\" href=\"http://odata.org/editlink\" />",
                        "  <link rel=\"self\" href=\"" + ObjectModelUtils.DefaultEntryReadLink.OriginalString + "\" />",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "Everything at the beginning, category with type name, edit and self link with ATOM metadata",
                    Entry = new ODataEntry() { TypeName = "MyType", Id = new Uri("http://odata.org/MyId"), ReadLink = ObjectModelUtils.DefaultEntryReadLink, EditLink = new Uri("http://odata.org/editlink"), SerializationInfo = infoMyType }
                        .WithAnnotation(new AtomEntryMetadata { 
                            EditLink = new AtomLinkMetadata { Title = "EditLinkTitle" },
                            SelfLink = new AtomLinkMetadata { Title = "SelfLinkTitle" },
                            CategoryWithTypeName = new AtomCategoryMetadata { Label = "TypeNameLabel" },
                            Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <id>urn:MyId</id>",
                        "  <category term=\"#MyType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" label=\"TypeNameLabel\" />",
                        "  <link rel=\"edit\" title=\"EditLinkTitle\" href=\"http://odata.org/editlink\" />",
                        "  <link rel=\"self\" title=\"SelfLinkTitle\" href=\"" + ObjectModelUtils.DefaultEntryReadLink.OriginalString + "\" />",
                        "{0}  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "Everything at the end, category with type name, edit and self link with ATOM metadata (from the beginning)",
                    Entry = new ODataEntry() { TypeName = "MyType", SerializationInfo = infoMyType }
                        .WithAnnotation(new WriteEntryCallbacksAnnotation {
                            BeforeWriteStartCallback = (entry) => { entry.Id = null; entry.ReadLink = null; entry.EditLink = null; },
                            BeforeWriteEndCallback = (entry) => { entry.Id = new Uri("http://odata.org/MyId"); entry.ReadLink = ObjectModelUtils.DefaultEntryReadLink; entry.EditLink = new Uri("http://odata.org/editlink"); }})
                        .WithAnnotation(new AtomEntryMetadata { 
                            EditLink = new AtomLinkMetadata { Title = "EditLinkTitle" },
                            SelfLink = new AtomLinkMetadata { Title = "SelfLinkTitle" },
                            CategoryWithTypeName = new AtomCategoryMetadata { Label = "TypeNameLabel" },
                            Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <category term=\"#MyType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" label=\"TypeNameLabel\" />",
                        "{0}  <id>urn:MyId</id>",
                        "  <link rel=\"edit\" title=\"EditLinkTitle\" href=\"http://odata.org/editlink\" />",
                        "  <link rel=\"self\" title=\"SelfLinkTitle\" href=\"" + ObjectModelUtils.DefaultEntryReadLink.OriginalString + "\" />",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <content type=\"application/xml\" />",
                        "</entry>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "With default stream and stream property, everything at the end",
                    Entry = new ODataEntry() { 
                            TypeName = "TestModel.AllInType",
                            MediaResource = new ODataStreamReferenceValue
                            {
                                ReadLink = new Uri("http://odata.org/mrreadlink"),
                                ContentType = "mr/type",
                                EditLink = new Uri("http://odata.org/mreditlink")
                            },
                            Properties = new []
                            {
                                new ODataProperty { Name = "ID", Value = 42 },
                                new ODataProperty { Name = "Name", Value = "foo" },
                                new ODataProperty { Name = "Description", Value = "bar" },
                                new ODataProperty { Name = "StreamProperty", Value = new ODataStreamReferenceValue
                                {
                                    ReadLink = new Uri("http://odata.org/streamproperty/readlink"),
                                    ContentType = "streamproperty/type",
                                    EditLink = new Uri("http://odata.org/streamproperty/editlink"),
                                }}
                            },
                            SerializationInfo = infoAllInType
                        }
                        .WithAnnotation(new WriteEntryCallbacksAnnotation {
                            BeforeWriteStartCallback = (entry) => { entry.Id = null; entry.ReadLink = null; entry.EditLink = null; },
                            BeforeWriteEndCallback = (entry) => { entry.Id = new Uri("http://odata.org/MyId"); entry.ReadLink = ObjectModelUtils.DefaultEntryReadLink; entry.EditLink = new Uri("http://odata.org/editlink"); }})
                        .WithAnnotation(new AtomEntryMetadata { 
                            EditLink = new AtomLinkMetadata { Title = "EditLinkTitle" },
                            SelfLink = new AtomLinkMetadata { Title = "SelfLinkTitle" },
                            CategoryWithTypeName = new AtomCategoryMetadata { Label = "TypeNameLabel" },
                            Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Model = model,
                    Xml = string.Join(
                        "$(NL)",
                        "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <category term=\"#TestModel.AllInType\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" label=\"TypeNameLabel\" />",
                        "{0}  <id>urn:MyId</id>",
                        "  <link rel=\"edit\" title=\"EditLinkTitle\" href=\"http://odata.org/editlink\" />",
                        "  <link rel=\"self\" title=\"SelfLinkTitle\" href=\"" + ObjectModelUtils.DefaultEntryReadLink.OriginalString + "\" />",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "  <link rel=\"http://docs.oasis-open.org/odata/ns/mediaresource/StreamProperty\" type=\"streamproperty/type\" title=\"StreamProperty\" href=\"http://odata.org/streamproperty/readlink\" />",
                        "  <link rel=\"http://docs.oasis-open.org/odata/ns/edit-media/StreamProperty\" type=\"streamproperty/type\" title=\"StreamProperty\" href=\"http://odata.org/streamproperty/editlink\" />",
                        "  <link rel=\"edit-media\" href=\"http://odata.org/mreditlink\" />",
                        "  <content type=\"mr/type\" src=\"http://odata.org/mrreadlink\" />",
                        "  <properties xmlns=\"http://docs.oasis-open.org/odata/ns/metadata\">",
                        "    <ID p3:type=\"Edm.Int32\" xmlns:p3=\"http://docs.oasis-open.org/odata/ns/metadata\" xmlns=\"http://docs.oasis-open.org/odata/ns/data\">42</ID>",
                        "    <Name xmlns=\"http://docs.oasis-open.org/odata/ns/data\">foo</Name>",
                        "    <Description xmlns=\"http://docs.oasis-open.org/odata/ns/data\">bar</Description>",
                        "  </properties>",
                        "</entry>"),
                    // Stream properties are not allowed in requests.
                    SkipTestConfiguration = tc => tc.IsRequest
                },
            };

            IEnumerable<PayloadWriterTestDescriptor<ODataItem>> testDescriptors = testCases.Select(testCase =>
                new PayloadWriterTestDescriptor<ODataItem>(
                    this.Settings,
                    new ODataItem[] { testCase.Entry },
                    tc => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Xml = string.Format(CultureInfo.InvariantCulture, testCase.Xml, string.Empty),
                        FragmentExtractor = (element) => element
                    })
                {
                    DebugDescription = testCase.DebugDescription,
                    Model = testCase.Model,
                    SkipTestConfiguration = testCase.SkipTestConfiguration
                });

            testDescriptors = testDescriptors.Concat(testCases.Select(testCase =>
                new PayloadWriterTestDescriptor<ODataItem>(
                    this.Settings,
                    new ODataItem[] { testCase.Entry, new ODataNavigationLink
                    {
                        Name = "NavProp",
                        IsCollection = true,
                        Url = new Uri("http://odata.org/navprop/uri")
                    }},
                    tc => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Xml = string.Format(CultureInfo.InvariantCulture, testCase.Xml, 
                            "  <link rel=\"" + TestAtomConstants.ODataNavigationPropertiesRelatedLinkRelationPrefix + "NavProp\" " +
                            "type=\"application/atom+xml;type=feed\" title=\"NavProp\" " +
                            "href=\"http://odata.org/navprop/uri\" />$(NL)"),
                        FragmentExtractor = (element) => element
                    })
                    {
                        DebugDescription = testCase.DebugDescription + "- with navigation property",
                        Model = testCase.Model,
                        SkipTestConfiguration = testCase.SkipTestConfiguration
                    }));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent,
                (testDescriptor, testConfiguration) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);
                    TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor.DeferredLinksToEntityReferenceLinksInRequest(testConfiguration), testConfiguration, this.Assert, this.Logger);
                });
        }
 /// <summary>
 /// Provide additional serialization information to the <see cref="ODataWriter"/> for <paramref name="feed"/>.
 /// </summary>
 /// <param name="feed">The instance to set the serialization info.</param>
 /// <param name="serializationInfo">The serialization info to set.</param>
 public static void SetSerializationInfo(this ODataFeed feed, ODataFeedAndEntrySerializationInfo serializationInfo)
 {
     ExceptionUtils.CheckArgumentNotNull(feed, "feed");
     feed.SerializationInfo = serializationInfo;
 }
Beispiel #16
0
        public void EmptyComplexValueTest()
        {
            ODataFeedAndEntrySerializationInfo info = new ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceEntityTypeName = "Null",
                NavigationSourceName = "MySet",
                ExpectedTypeName = "Null"
            };

            var testDescriptors = new[]
            {
                // Empty entry level complex value -> no property written and no m:properties included either
                new PayloadWriterTestDescriptor<ODataItem>(
                    this.Settings,
                    new ODataEntry() {
                        Properties = new [] { new ODataProperty { Name = "EmptyComplex", Value =
                            new ODataComplexValue { Properties = null }
                        } },
                        SerializationInfo = info
                    },
                    (tc) => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) {
                        Xml = "<root/>",
                        FragmentExtractor = (result) => new XElement("root", result
                            .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomContentElementName)
                            .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomPropertiesElementName))
                    }),
                // Empty second level complex value -> no property written and no m:properties included either
                new PayloadWriterTestDescriptor<ODataItem>(
                    this.Settings,
                    new ODataEntry() { Properties = new [] { new ODataProperty { Name = "OuterComplex", Value =
                        new ODataComplexValue { Properties = new [] { new ODataProperty { Name = "InnerComplex", Value =
                            new ODataComplexValue { Properties = null } 
                        } } }
                    } },
                    SerializationInfo = info},
                    (tc) => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) {
                        Xml = "<root/>",
                        FragmentExtractor = (result) => new XElement("root", result
                            .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomContentElementName)
                            .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomPropertiesElementName))
                    }),
                // Empty second level complex value in collection
                new PayloadWriterTestDescriptor<ODataItem>(
                    this.Settings,
                    new ODataEntry() { Properties = new [] { new ODataProperty { Name = "ComplexCollection", Value = new ODataCollectionValue { Items = new [] {
                        new ODataComplexValue { Properties = new [] { new ODataProperty { Name = "InnerComplex", Value =
                            new ODataComplexValue { Properties = null } 
                        } } }
                    } } } },
                    SerializationInfo = info},
                    (tc) => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) {
                        Xml = string.Format("<{0}:ComplexCollection xmlns:{0}='{1}' xmlns:{2}='{3}'><{2}:element/></{0}:ComplexCollection>",
                            TestAtomConstants.ODataNamespacePrefix,
                            TestAtomConstants.ODataNamespace,
                            TestAtomConstants.ODataMetadataNamespacePrefix,
                            TestAtomConstants.ODataMetadataNamespace),
                        FragmentExtractor = (result) => TestAtomUtils.ExtractPropertiesFromEntry(result)
                            .Element(TestAtomConstants.ODataXNamespace + "ComplexCollection")
                    })            
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent,
                (testDescriptor, testConfiguration) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
                });
        }
        public void WritingInFullMetadataModeWithExpandAndProjectionWithMissingStreamAndActionAndFunctionWhenAutoComputePayloadMetadataInJsonIsTrue()
        {
            const string expectedPayload =
                "{" +
                    "\"@odata.context\":\"http://example.com/$metadata#EntitySet(StreamProp1,Namespace.AlwaysBindableAction1,Namespace.AlwaysBindableFunction1,DeferredNavLink,ExpandedNavLink,ExpandedNavLink(StreamProp1,Namespace.AlwaysBindableAction1,ExpandedNavLink,ExpandedNavLink(StreamProp2,Namespace.AlwaysBindableAction1)))\"," +
                    "\"value\":[" +
                    "{" +
                        "\"@odata.type\":\"#Namespace.EntityType\"," +
                        "\"@odata.id\":\"EntitySet(123)\"," +
                        "\"@odata.etag\":\"W/\\\"'Bob'\\\"\"," +
                        "\"@odata.editLink\":\"EntitySet(123)\"," +
                        "\"@odata.mediaEditLink\":\"EntitySet(123)/$value\"," +
                        "\"ID\":123," +
                        "\"Name\":\"Bob\"," +
                        "\"[email protected]\":\"http://example.com/expanded/association\"," +
                        "\"[email protected]\":\"http://example.com/expanded/navigation\"," +
                        "\"ExpandedNavLink\":[" +
                        "{" +
                            "\"@odata.type\":\"#Namespace.EntityType\"," +
                            "\"@odata.id\":\"EntitySet(234)\"," +
                            "\"@odata.etag\":\"W/\\\"'Foo'\\\"\"," +
                            "\"@odata.editLink\":\"EntitySet(234)\"," +
                            "\"@odata.mediaEditLink\":\"EntitySet(234)/$value\"," +
                            "\"ID\":234," +
                            "\"Name\":\"Foo\"," +
                            "\"[email protected]\":\"http://example.com/EntitySet(234)/DeferredNavLink/$ref\"," +
                            "\"[email protected]\":\"http://example.com/EntitySet(234)/DeferredNavLink\"," +
                            "\"[email protected]\":\"http://example.com/EntitySet(234)/ExpandedNavLink/$ref\"," +
                            "\"[email protected]\":\"http://example.com/EntitySet(234)/ExpandedNavLink\"," +
                            "\"ExpandedNavLink\":[" +
                            "{" +
                                "\"@odata.type\":\"#Namespace.EntityType\"," +
                                "\"@odata.id\":\"EntitySet(345)\"," +
                                "\"@odata.etag\":\"W/\\\"'Bar'\\\"\"," +
                                "\"@odata.editLink\":\"EntitySet(345)\"," +
                                "\"@odata.mediaEditLink\":\"EntitySet(345)/$value\"," +
                                "\"ID\":345," +
                                "\"Name\":\"Bar\"" +
                            "}]" +
                        "}]" +
                    "}]" +
                "}";

            ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = EntitySet.Name, NavigationSourceEntityTypeName = EntityType.FullName(), ExpectedTypeName = EntityType.FullName() };

            var feed = new ODataFeed();
            feed.SetSerializationInfo(serializationInfo);
            this.entryWithOnlyData.TypeName = EntityType.FullName();
            this.entryWithOnlyData.MediaResource = new ODataStreamReferenceValue();
            this.entryWithOnlyData.Properties.First(p => p.Name == "ID").SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key });
            this.entryWithOnlyData.Properties.First(p => p.Name == "Name").SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.ETag });
            this.entryWithOnlyData2.TypeName = EntityType.FullName();
            this.entryWithOnlyData2.MediaResource = new ODataStreamReferenceValue();
            this.entryWithOnlyData2.Properties.First(p => p.Name == "ID").SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key });
            this.entryWithOnlyData2.Properties.First(p => p.Name == "Name").SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.ETag });
            this.entryWithOnlyData3.TypeName = EntityType.FullName();
            this.entryWithOnlyData3.MediaResource = new ODataStreamReferenceValue();
            this.entryWithOnlyData3.Properties.First(p => p.Name == "ID").SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key });
            this.entryWithOnlyData3.Properties.First(p => p.Name == "Name").SetSerializationInfo(new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.ETag });

            ODataItem[] itemsToWrite = new ODataItem[]
            {
                feed, this.entryWithOnlyData,
                this.expandedNavLinkWithPayloadMetadata, feed, this.entryWithOnlyData2, this.navLinkWithoutPayloadMetadata,
                this.expandedNavLinkWithoutPayloadMetadata, feed, this.entryWithOnlyData3
            };

            const string selectClause = "StreamProp1,Namespace.AlwaysBindableAction1,Namespace.AlwaysBindableFunction1,DeferredNavLink";
            const string expandClause = "ExpandedNavLink($select=StreamProp1,Namespace.AlwaysBindableAction1;$expand=ExpandedNavLink($select=StreamProp2,Namespace.AlwaysBindableAction1))";
            this.GetWriterOutputForContentTypeAndKnobValue("application/json;odata.metadata=full", true, itemsToWrite, edmModel: Model, edmEntitySet: null, edmEntityType: EntityType, selectClause: selectClause, expandClause: expandClause)
                .Should().Be(expectedPayload);
        }
 /// <summary>
 /// Provide additional serialization information to the <see cref="ODataWriter"/> for <paramref name="entry"/>.
 /// </summary>
 /// <param name="entry">The instance to set the serialization info.</param>
 /// <param name="serializationInfo">The serialization info to set.</param>
 public static void SetSerializationInfo(this ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo)
 {
     ExceptionUtils.CheckArgumentNotNull(entry, "entry");
     entry.SerializationInfo = serializationInfo;
 }
 public void EntryContextUriShouldNotBeWrittenIfNotProvided()
 {
     var serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "MyContainer.MyCities", NavigationSourceEntityTypeName = "TestModel.MyCity", ExpectedTypeName = "TestModel.MyCity" };
     var typeContext = ODataFeedAndEntryTypeContext.Create(serializationInfo, null, null, null, EdmCoreModel.Instance, true);
     this.builderWithNoMetadataDocumentUri.BuildContextUri(ODataPayloadKind.Entry, ODataContextUrlInfo.Create(typeContext, true)).Should().BeNull();
 }
 public void ShouldNotIncludeEntityOnSingletonWithoutModel()
 {
     ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo() { ExpectedTypeName = "People", NavigationSourceEntityTypeName = "People", NavigationSourceName = "Boss", NavigationSourceKind = EdmNavigationSourceKind.Singleton, };
     var requestSingletonTypeContextWithoutModel = ODataFeedAndEntryTypeContext.Create(serializationInfo, /*navigationSource*/null, /*navigationSourceEntityType*/null, /*expectedEntityType*/null, EdmCoreModel.Instance, true);
     this.CreateEntryContextUri(requestSingletonTypeContextWithoutModel).OriginalString.Should().Be(BuildExpectedContextUri("#Boss", false));
 }
        public void WritingInMinimalMetadataModeWithExpandAndProjectionWithModelWhenAutoComputePayloadMetadataInJsonIsTrue()
        {
            const string expectedPayload =
                "{" +
                    "\"@odata.context\":\"http://example.com/$metadata#EntitySet(StreamProp1,Namespace.AlwaysBindableAction1,Namespace.AlwaysBindableFunction1,DeferredNavLink,ExpandedNavLink,ExpandedNavLink(StreamProp1,Namespace.AlwaysBindableAction1,ExpandedNavLink,ExpandedNavLink(StreamProp2,Namespace.AlwaysBindableAction1)))\"," +
                    "\"value\":[" +
                    "{" +
                        "\"ID\":123," +
                        "\"Name\":\"Bob\"," +
                        "\"[email protected]\":\"http://example.com/expanded/association\"," +
                        "\"[email protected]\":\"http://example.com/expanded/navigation\"," +
                        "\"ExpandedNavLink\":[" +
                        "{" +
                            "\"ID\":234," +
                            "\"Name\":\"Foo\"," +
                            "\"ExpandedNavLink\":[" +
                            "{" +
                                "\"ID\":345," +
                                "\"Name\":\"Bar\"," +
                                "\"#Container.AlwaysBindableAction1\":{}" +
                            "}]," +
                            "\"#Container.AlwaysBindableAction1\":{}" +
                        "}]," +
                        "\"#Container.AlwaysBindableAction1\":{}," +
                        "\"#Container.AlwaysBindableFunction1\":{}" +
                    "}]" +
                "}";

            ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = EntitySet.Name, NavigationSourceEntityTypeName = EntityType.FullName(), ExpectedTypeName = EntityType.FullName() };

            var feed = new ODataFeed();
            feed.SetSerializationInfo(serializationInfo);

            this.entryWithOnlyData = new ODataEntry
            {
                TypeName = EntityType.FullName(),
                MediaResource = new ODataStreamReferenceValue(),
                Properties = new[]
                {
                    new ODataProperty { Name = "ID", Value = 123, SerializationInfo = new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key }},
                    new ODataProperty { Name = "Name", Value = "Bob", SerializationInfo = new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.ETag }},
                    new ODataProperty { Name = "StreamProp1", Value = new ODataStreamReferenceValue() }
                },
            };
            this.entryWithOnlyData.AddAction(new ODataAction { Metadata = new Uri("http://example.com/$metadata#Container.AlwaysBindableAction1") });
            this.entryWithOnlyData.AddFunction(new ODataFunction { Metadata = new Uri("#Container.AlwaysBindableFunction1", UriKind.Relative) });

            this.entryWithOnlyData2 = new ODataEntry
            {
                TypeName = EntityType.FullName(),
                MediaResource = new ODataStreamReferenceValue(),
                Properties = new[]
                {
                    new ODataProperty { Name = "ID", Value = 234, SerializationInfo = new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key }},
                    new ODataProperty { Name = "Name", Value = "Foo", SerializationInfo = new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.ETag }},
                    new ODataProperty { Name = "StreamProp1", Value = new ODataStreamReferenceValue() }
                },
            };
            this.entryWithOnlyData2.AddAction(new ODataAction { Metadata = new Uri("http://example.com/$metadata#Container.AlwaysBindableAction1") });

            this.entryWithOnlyData3 = new ODataEntry
            {
                TypeName = EntityType.FullName(),
                MediaResource = new ODataStreamReferenceValue(),
                Properties = new[]
                {
                    new ODataProperty { Name = "ID", Value = 345, SerializationInfo = new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.Key }},
                    new ODataProperty { Name = "Name", Value = "Bar", SerializationInfo = new ODataPropertySerializationInfo { PropertyKind = ODataPropertyKind.ETag }},
                    new ODataProperty { Name = "StreamProp2", Value = new ODataStreamReferenceValue() }
                },
            };
            this.entryWithOnlyData3.AddAction(new ODataAction { Metadata = new Uri("http://example.com/$metadata#Container.AlwaysBindableAction1") });

            ODataItem[] itemsToWrite = new ODataItem[]
            {
                feed, this.entryWithOnlyData,
                this.expandedNavLinkWithPayloadMetadata, feed, this.entryWithOnlyData2, this.navLinkWithoutPayloadMetadata,
                this.expandedNavLinkWithoutPayloadMetadata, feed, this.entryWithOnlyData3
            };

            const string selectClause = "StreamProp1,Namespace.AlwaysBindableAction1,Namespace.AlwaysBindableFunction1,DeferredNavLink";
            const string expandClause = "ExpandedNavLink($select=StreamProp1,Namespace.AlwaysBindableAction1;$expand=ExpandedNavLink($select=StreamProp2,Namespace.AlwaysBindableAction1))";
            this.GetWriterOutputForContentTypeAndKnobValue("application/json;odata.metadata=minimal", true, itemsToWrite, edmModel: Model, edmEntitySet: null, edmEntityType: EntityType, selectClause: selectClause, expandClause: expandClause)
                .Should().Be(expectedPayload);
        }
 /// <summary>
 /// Provide additional serialization information to the <see cref="ODataWriter"/> for <paramref name="feed"/>.
 /// </summary>
 /// <param name="feed">The instance to set the serialization info.</param>
 /// <param name="serializationInfo">The serialization info to set.</param>
 public static void SetSerializationInfo(this ODataFeed feed, ODataFeedAndEntrySerializationInfo serializationInfo)
 {
     ExceptionUtils.CheckArgumentNotNull(feed, "feed");
     feed.SerializationInfo = serializationInfo;
 }
Beispiel #23
0
            /// <summary>
            /// Constructor to create a new entry scope.
            /// </summary>
            /// <param name="entry">The entry for the new scope.</param>
            /// <param name="serializationInfo">The serialization info for the current entry.</param>
            /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
            /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
            /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
            /// <param name="writingResponse">true if we are writing a response, false if it's a request.</param>
            /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
            /// <param name="selectedProperties">The selected properties of this scope.</param>
            /// <param name="odataUri">The ODataUri info of this scope.</param>
            /// <param name="enableValidation">Enable validation or not.</param>
            internal EntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri, bool enableValidation = true)
                : base(WriterState.Entry, entry, navigationSource, entityType, skipWriting, selectedProperties, odataUri)
            {
                Debug.Assert(writerBehavior != null, "writerBehavior != null");

                if (entry != null)
                {
                    this.duplicatePropertyNamesChecker = new DuplicatePropertyNamesChecker(writerBehavior.AllowDuplicatePropertyNames, writingResponse, !enableValidation);
                }

                this.serializationInfo = serializationInfo;
            }
 /// <summary>
 /// Provide additional serialization information to the <see cref="ODataWriter"/> for <paramref name="entry"/>.
 /// </summary>
 /// <param name="entry">The instance to set the serialization info.</param>
 /// <param name="serializationInfo">The serialization info to set.</param>
 public static void SetSerializationInfo(this ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo)
 {
     ExceptionUtils.CheckArgumentNotNull(entry, "entry");
     entry.SerializationInfo = serializationInfo;
 }
 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 PayloadOrderTest()
        {
            ODataFeedAndEntrySerializationInfo info = new ODataFeedAndEntrySerializationInfo()
            {
                NavigationSourceEntityTypeName = "Null",
                NavigationSourceName = "MySet",
                ExpectedTypeName = "Null"
            };

            AtomFeedMetadata defaultAtomFeedMetadata = new AtomFeedMetadata() { 
                Authors = new[] { new AtomPersonMetadata { Name = "Bart" } }, 
                Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime };

            IEnumerable<PayloadOrderTestCase> testCases = new[]
            {
                new PayloadOrderTestCase
                {
                    DebugDescription = "Just ID",
                    Feed = new ODataFeed() { Id = new Uri("http://MyFeedId"), SerializationInfo = info }
                        .WithAnnotation(defaultAtomFeedMetadata),
                    Xml = string.Join(
                        "$(NL)",
                        "<feed xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <id>http://MyFeedId</id>",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name>Bart</name>",
                        "  </author>{0}",
                        "</feed>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "Just ID, and another ID at the end, the one from the starts is used",
                    Feed = new ODataFeed() { SerializationInfo = info }
                        .WithAnnotation(new WriteFeedCallbacksAnnotation
                            {
                                BeforeWriteStartCallback = (feed) => { feed.Id = new Uri("http://MyFeedId"); },
                                BeforeWriteEndCallback = (feed) => { feed.Id = new Uri("http://AnotherFeedId"); }
                            })
                        .WithAnnotation(defaultAtomFeedMetadata),
                    Xml = string.Join(
                        "$(NL)",
                        "<feed xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <id>http://MyFeedId</id>",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name>Bart</name>",
                        "  </author>{0}",
                        "</feed>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "ID and no author metadata and no entities, the default author should be written.",
                    Feed = new ODataFeed() { Id = new Uri("http://MyFeedId"), SerializationInfo = info }
                        .WithAnnotation(new AtomFeedMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<feed xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <id>http://MyFeedId</id>",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>{0}",
                        "  <author>",
                        "    <name />",
                        "  </author>",
                        "</feed>"),
                    NoEntitiesOnly = true
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "ID and no author metadata but with entities, no author is written.",
                    Feed = new ODataFeed() { Id = new Uri("http://MyFeedId"), SerializationInfo = info }
                        .WithAnnotation(new AtomFeedMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    Xml = string.Join(
                        "$(NL)",
                        "<feed xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <id>http://MyFeedId</id>",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>{0}",
                        "</feed>"),
                    WithEntitiesOnly = true
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "ID, count at the end - the count is ignored",
                    Feed = new ODataFeed() { Id = new Uri("http://MyFeedId"), SerializationInfo = info }
                        .WithAnnotation(new WriteFeedCallbacksAnnotation
                            {
                                BeforeWriteStartCallback = (feed) => { feed.Count = null; },
                                BeforeWriteEndCallback = (feed) => { feed.Count = 42; }
                            })
                        .WithAnnotation(defaultAtomFeedMetadata),
                    Xml = string.Join(
                        "$(NL)",
                        "<feed xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <id>http://MyFeedId</id>",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name>Bart</name>",
                        "  </author>{0}",
                        "</feed>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "ID, count and next link",
                    Feed = new ODataFeed() { Id = new Uri("http://MyFeedId"), Count = 42, NextPageLink = new Uri("http://odata.org/nextlink"), SerializationInfo = info  }
                        .WithAnnotation(defaultAtomFeedMetadata),
                    Xml = string.Join(
                        "$(NL)",
                        "<feed xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <count xmlns=\"http://docs.oasis-open.org/odata/ns/metadata\">42</count>",
                        "  <id>http://MyFeedId</id>",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <author>",
                        "    <name>Bart</name>",
                        "  </author>{0}",
                        "  <link rel=\"next\" href=\"http://odata.org/nextlink\" />",
                        "</feed>"),
                },
                new PayloadOrderTestCase
                {
                    DebugDescription = "ID, count and next link and some ATOM metadata, metadata goes before entries but author is the last of them.",
                    Feed = new ODataFeed() { Id = new Uri("http://MyFeedId"), Count = 42, NextPageLink = new Uri("http://odata.org/nextlink"), SerializationInfo = info }
                        .WithAnnotation(new AtomFeedMetadata() { 
                            Authors = new[] { new AtomPersonMetadata { Name = "Bart" } }, 
                            Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime,
                            Logo = new Uri("http://odata.org/logo") }),
                    Xml = string.Join(
                        "$(NL)",
                        "<feed xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                        "  <count xmlns=\"http://docs.oasis-open.org/odata/ns/metadata\">42</count>",
                        "  <id>http://MyFeedId</id>",
                        "  <title />",
                        "  <updated>2010-10-12T17:13:00Z</updated>",
                        "  <logo>http://odata.org/logo</logo>",
                        "  <author>",
                        "    <name>Bart</name>",
                        "  </author>{0}",
                        "  <link rel=\"next\" href=\"http://odata.org/nextlink\" />",
                        "</feed>"),
                },
            };

            IEnumerable<PayloadWriterTestDescriptor<ODataItem>> testDescriptors = testCases.Where(testCase => !testCase.WithEntitiesOnly).Select(testCase =>
                new PayloadWriterTestDescriptor<ODataItem>(
                    this.Settings,
                    new ODataItem[] { testCase.Feed },
                    tc => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Xml = string.Format(CultureInfo.InvariantCulture, testCase.Xml, string.Empty),
                        FragmentExtractor = (element) => element
                    })
                {
                    DebugDescription = testCase.DebugDescription,
                });

            testDescriptors = testDescriptors.Concat(testCases.Where(testCase => !testCase.NoEntitiesOnly).Select(testCase =>
                new PayloadWriterTestDescriptor<ODataItem>(
                    this.Settings,
                    new ODataItem[] { 
                        testCase.Feed, 
                        new ODataEntry { }
                            .WithAnnotation(new AtomEntryMetadata { Updated = ObjectModelUtils.DefaultEntryUpdatedDateTime }),
                    },
                    tc => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Xml = string.Format(CultureInfo.InvariantCulture, testCase.Xml,
                            string.Join(
                                "$(NL)",
                                "<entry xmlns=\"" + TestAtomConstants.AtomNamespace + "\">",
                                "  <id />",
                                "  <title />",
                                "  <updated>2010-10-12T17:13:00Z</updated>",
                                "  <author>",
                                "    <name />",
                                "  </author>",
                                "  <content type=\"application/xml\" />",
                                "</entry>")),
                        FragmentExtractor = (element) => element
                    })
                {
                    DebugDescription = testCase.DebugDescription + "- with entry",
                }));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent
                    .Where(tc => !tc.IsRequest),
                (testDescriptor, testConfiguration) =>
                {
                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
                });
        }
 /// <summary>
 /// Constructs an instance of <see cref="ODataFeedAndEntryTypeContext"/>.
 /// </summary>
 /// <param name="serializationInfo">The serialization info from the feed or entry instance.</param>
 internal ODataFeedAndEntryTypeContextWithoutModel(ODataFeedAndEntrySerializationInfo serializationInfo)
     : base(/*throwIfMissingTypeInfo*/ false)
 {
     Debug.Assert(serializationInfo != null, "serializationInfo != null");
     this.serializationInfo = serializationInfo;
 }
 public void TestInit()
 {
     this.testSubject = new ODataFeedAndEntrySerializationInfo();
 }