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; }
/// <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=\""etag1"\" 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; }
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> /// 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; }
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(); }