public ODataEntryTests() { this.odataEntry = new ODataEntry(); this.odataEntryWithFullBuilder = 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(this.odataEntryWithFullBuilder, typeContext, serializationInfo, null, metadataContext, SelectedPropertiesNode.EntireSubtree); this.odataEntryWithFullBuilder.MetadataBuilder = new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, new ODataConventionalUriBuilder(new Uri("http://service/", UriKind.Absolute), UrlConvention.CreateWithExplicitValue(false))); this.odataEntryWithNullBuilder = new ODataEntry { MetadataBuilder = ODataEntityMetadataBuilder.Null }; }
public void ShouldBeAbleToSetTheEntrySerializationInfo() { ODataEntry entry = new ODataEntry(); ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set", NavigationSourceEntityTypeName = "ns.base", ExpectedTypeName = "ns.expected" }; entry.SetSerializationInfo(serializationInfo); entry.SerializationInfo.Should().BeSameAs(serializationInfo); }
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" }; SerializationInfoWithEdmUnknowEntitySet = new ODataFeedAndEntrySerializationInfo() { NavigationSourceName = null, NavigationSourceEntityTypeName = "ns.MyCustomer", ExpectedTypeName = "ns.MyVipCustomer", NavigationSourceKind = EdmNavigationSourceKind.UnknownEntitySet }; 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); TypeContextWithEdmUnknowEntitySet = ODataFeedAndEntryTypeContext.Create(SerializationInfoWithEdmUnknowEntitySet, navigationSource: null, navigationSourceEntityType: null, expectedEntityType: null, model: 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); }
public ODataNavigationLinkTests() { 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> /// Constructs an instance of <see cref="ODataEntryMetadataContextWithoutModel"/>. /// </summary> /// <param name="entry">The entry instance.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param> internal ODataEntryMetadataContextWithoutModel(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo) : base(entry, typeContext) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(serializationInfo != null, "serializationInfo != null"); this.serializationInfo = serializationInfo; }
/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <param name="odataUri">The OData Uri.</param> /// <returns>The created metadata builder.</returns> internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool?keyAsSegment, ODataUri odataUri) { Debug.Assert(entry != null, "entry != null"); Debug.Assert(typeContext != null, "typeContext != null"); Debug.Assert(selectedProperties != null, "selectedProperties != null"); IODataMetadataContext metadataContext = new ODataMetadataContext( isResponse, this.model, this.NonNullMetadataDocumentUri, odataUri); UrlConvention urlConvention = UrlConvention.ForUserSettingAndTypeContext(keyAsSegment, typeContext); ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(metadataContext.ServiceBaseUri, urlConvention); IODataEntryMetadataContext entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, actualEntityType, metadataContext, selectedProperties); return(new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, uriBuilder)); }
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); }
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); }
public void InitTest() { this.testSubject = new ODataStreamReferenceValue(); 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.streamWithFullBuilder = new ODataStreamReferenceValue(); this.streamWithFullBuilder.SetMetadataBuilder(fullMetadataBuilder, "Stream"); }
/// <summary> /// Get key value pair array for specifc odata entry using specifc entity type /// </summary> /// <param name="entry">The entry instance.</param> /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param> /// <param name="actualEntityType">The edm entity type of the entry</param> /// <returns>Key value pair array</returns> internal static KeyValuePair <string, object>[] GetKeyProperties( ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType) { KeyValuePair <string, object>[] keyProperties = null; string actualEntityTypeName = null; if (serializationInfo != null) { if (String.IsNullOrEmpty(entry.TypeName)) { throw new ODataException(OData.Core.Strings.ODataFeedAndEntryTypeContext_ODataEntryTypeNameMissing); } actualEntityTypeName = entry.TypeName; keyProperties = ODataEntryMetadataContextWithoutModel.GetPropertiesBySerializationInfoPropertyKind(entry, ODataPropertyKind.Key, actualEntityTypeName); } else { actualEntityTypeName = actualEntityType.FullName(); IEnumerable <IEdmStructuralProperty> edmKeyProperties = actualEntityType.Key(); if (edmKeyProperties != null) { keyProperties = edmKeyProperties.Select(p => new KeyValuePair <string, object>(p.Name, GetPrimitivePropertyClrValue(entry, p.Name, actualEntityTypeName, /*isKeyProperty*/ false))).ToArray(); } } ValidateEntityTypeHasKeyProperties(keyProperties, actualEntityTypeName); return(keyProperties); }
/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <returns>The created metadata builder.</returns> internal abstract ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool?keyAsSegment);
public void ValidatingSerializationInfoShouldThrowIfBaseTypeNameNotSet() { Action action = () => ODataFeedAndEntrySerializationInfo.Validate(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set" }); action.ShouldThrow <ArgumentNullException>().WithMessage("serializationInfo.NavigationSourceEntityTypeName", ComparisonMode.Substring); }
public void ShouldBeAbleToClearTheFeedSerializationInfo() { ODataFeed feed = new ODataFeed(); ODataFeedAndEntrySerializationInfo serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set", NavigationSourceEntityTypeName = "ns.base", ExpectedTypeName = "ns.expected" }; feed.SerializationInfo = serializationInfo; feed.SetSerializationInfo(null); feed.SerializationInfo.Should().BeNull(); }
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)); }
/// <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) { DebugUtils.CheckNoExternalCallers(); if (serializationInfo != null) { ExceptionUtils.CheckArgumentNotNull(serializationInfo.EntitySetName, "serializationInfo.EntitySetName"); ExceptionUtils.CheckArgumentNotNull(serializationInfo.EntitySetElementTypeName, "serializationInfo.EntitySetElementTypeName"); } return(serializationInfo); }
public void ValdatingSerializationInfoShouldAllowIfEntitySetNameNotSetWithEdmUnknownEntitySet() { ODataFeedAndEntrySerializationInfo.Validate(new ODataFeedAndEntrySerializationInfo() { ExpectedTypeName = "NS.Type", IsFromCollection = true, NavigationSourceEntityTypeName = "NS.Type", NavigationSourceKind = EdmNavigationSourceKind.UnknownEntitySet, NavigationSourceName = null }); }
/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <param name="odataUri">The OData Uri.</param> /// <returns>The created metadata builder.</returns> internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool?keyAsSegment, ODataUri odataUri) { return(ODataEntityMetadataBuilder.Null); }
/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <param name="odataUri">The OData Uri.</param> /// <returns>The created metadata builder.</returns> internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool? keyAsSegment, ODataUri odataUri) { return ODataEntityMetadataBuilder.Null; }
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); }
/// <summary> /// Creates an instance of <see cref="ODataEntryMetadataContext"/>. /// </summary> /// <param name="entry">The entry instance.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="metadataContext">The metadata context to use.</param> /// <param name="selectedProperties">The selected properties.</param> /// <returns>A new instance of <see cref="ODataEntryMetadataContext"/>.</returns> internal static ODataEntryMetadataContext Create( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, IODataMetadataContext metadataContext, SelectedPropertiesNode selectedProperties) { if (serializationInfo != null) { return(new ODataEntryMetadataContextWithoutModel(entry, typeContext, serializationInfo)); } return(new ODataEntryMetadataContextWithModel(entry, typeContext, actualEntityType, metadataContext, selectedProperties)); }
/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in separate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <param name="odataUri">The OData Uri.</param> /// <returns>The created metadata builder.</returns> internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool? keyAsSegment, ODataUri odataUri) { // For minimal metadata we don't want to change the metadata builder that's currently on the entry because the entry might come from a JSON light // reader and it would contain the metadata builder from the reader. Until we give the user the ability to choose whether to write what was reported // by the reader versus what was on the wire, we no-op here so the writer will just write what's on the OM for now. return null; }
/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <param name="odataUri">The OData Uri.</param> /// <returns>The created metadata builder.</returns> internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool?keyAsSegment, ODataUri odataUri) { // For minimal metadata we don't want to change the metadata builder that's currently on the entry because the entry might come from a JSON light // reader and it would contain the metadata builder from the reader. Until we give the user the ability to choose whether to write what was reported // by the reader versus what was on the wire, we no-op here so the writer will just write what's on the OM for now. return(null); }
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); }
public ODataNavigationLinkTests() { 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; }
public ODataEntryTests() { this.odataEntry = new ODataEntry(); this.odataEntryWithFullBuilder = 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(this.odataEntryWithFullBuilder, typeContext, serializationInfo, null, metadataContext, SelectedPropertiesNode.EntireSubtree); this.odataEntryWithFullBuilder.MetadataBuilder = new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, new ODataConventionalUriBuilder(new Uri("http://service/", UriKind.Absolute), UrlConvention.CreateWithExplicitValue(false))); this.odataEntryWithNullBuilder = new ODataEntry {MetadataBuilder = ODataEntityMetadataBuilder.Null}; }
public ODataOperationTests() { 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); }
/// <summary> /// Constructs an instance of <see cref="ODataEntryMetadataContextWithoutModel"/>. /// </summary> /// <param name="entry">The entry instance.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param> internal ODataEntryMetadataContextWithoutModel(ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo) : base(entry, typeContext) { Debug.Assert(serializationInfo != null, "serializationInfo != null"); this.serializationInfo = serializationInfo; }
/// <summary> /// Get key value pair array for specifc odata entry using specifc entity type /// </summary> /// <param name="entry">The entry instance.</param> /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param> /// <param name="actualEntityType">The edm entity type of the entry</param> /// <returns>Key value pair array</returns> internal static KeyValuePair<string, object>[] GetKeyProperties( ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType) { KeyValuePair<string, object>[] keyProperties = null; string actualEntityTypeName = null; if (serializationInfo != null) { if (String.IsNullOrEmpty(entry.TypeName)) { throw new ODataException(OData.Core.Strings.ODataFeedAndEntryTypeContext_ODataEntryTypeNameMissing); } actualEntityTypeName = entry.TypeName; keyProperties = ODataEntryMetadataContextWithoutModel.GetPropertiesBySerializationInfoPropertyKind(entry, ODataPropertyKind.Key, actualEntityTypeName); } else { actualEntityTypeName = actualEntityType.FullName(); IEnumerable<IEdmStructuralProperty> edmKeyProperties = actualEntityType.Key(); if (edmKeyProperties != null) { keyProperties = edmKeyProperties.Select(p => new KeyValuePair<string, object>(p.Name, GetPrimitivePropertyClrValue(entry, p.Name, actualEntityTypeName, /*isKeyProperty*/false))).ToArray(); } } ValidateEntityTypeHasKeyProperties(keyProperties, actualEntityTypeName); return keyProperties; }
/// <summary> /// Creates an instance of <see cref="ODataEntryMetadataContext"/>. /// </summary> /// <param name="entry">The entry instance.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="serializationInfo">The serialization info of the entry for writing without model.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="metadataContext">The metadata context to use.</param> /// <param name="selectedProperties">The selected properties.</param> /// <returns>A new instance of <see cref="ODataEntryMetadataContext"/>.</returns> internal static ODataEntryMetadataContext Create( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, IODataMetadataContext metadataContext, SelectedPropertiesNode selectedProperties) { if (serializationInfo != null) { return new ODataEntryMetadataContextWithoutModel(entry, typeContext, serializationInfo); } return new ODataEntryMetadataContextWithModel(entry, typeContext, actualEntityType, metadataContext, selectedProperties); }
public void ValidatingSerializationInfoShouldAllowExpectedTypeNameNotSet() { ODataFeedAndEntrySerializationInfo.Validate(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set", NavigationSourceEntityTypeName = "EntitySetElementTypeName" }).Should().NotBeNull(); }
/// <summary> /// Creates the metadata builder for the given entry. If such a builder is set, asking for payload /// metadata properties (like EditLink) of the entry may return a value computed by convention, /// depending on the metadata level and whether the user manually set an edit link or not. /// </summary> /// <param name="entry">The entry to create the metadata builder for.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="serializationInfo">The serialization info for the entry.</param> /// <param name="actualEntityType">The entity type of the entry.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> /// <param name="isResponse">true if the entity metadata builder to create should be for a response payload; false for a request.</param> /// <param name="keyAsSegment">true if keys should go in seperate segments in auto-generated URIs, false if they should go in parentheses. /// A null value means the user hasn't specified a preference and we should look for an annotation in the entity container, if available.</param> /// <param name="odataUri">The OData Uri.</param> /// <returns>The created metadata builder.</returns> internal override ODataEntityMetadataBuilder CreateEntityMetadataBuilder( ODataEntry entry, IODataFeedAndEntryTypeContext typeContext, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntityType actualEntityType, SelectedPropertiesNode selectedProperties, bool isResponse, bool? keyAsSegment, ODataUri odataUri) { Debug.Assert(entry != null, "entry != null"); Debug.Assert(typeContext != null, "typeContext != null"); Debug.Assert(selectedProperties != null, "selectedProperties != null"); IODataMetadataContext metadataContext = new ODataMetadataContext( isResponse, this.model, this.NonNullMetadataDocumentUri, odataUri); UrlConvention urlConvention = UrlConvention.ForUserSettingAndTypeContext(keyAsSegment, typeContext); ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(metadataContext.ServiceBaseUri, urlConvention); IODataEntryMetadataContext entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, actualEntityType, metadataContext, selectedProperties); return new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, uriBuilder); }
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); }
public void ValidateNullSerializationInfoShouldReturnNull() { ODataFeedAndEntrySerializationInfo.Validate(null).Should().BeNull(); }
/// <summary> /// Constructor to create a new delta link scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <param name="link">The link 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="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> protected DeltaLinkScope(WriterState state, ODataItem link, ODataDeltaSerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, link, navigationSource, entityType, selectedProperties, odataUri) { Debug.Assert(link != null, "link != null"); Debug.Assert( state == WriterState.DeltaLink && link is ODataDeltaLink || state == WriterState.DeltaDeletedLink && link is ODataDeltaDeletedLink, "link must be either DeltaLink or DeltaDeletedLink."); Debug.Assert(writerBehavior != null, "writerBehavior != null"); this.serializationInfo = DeltaConverter.ToFeedAndEntrySerializationInfo(serializationInfo); }
/// <summary> /// Constructor to create a new entry scope. /// </summary> /// <param name="state">The writer state of this scope.</param> /// <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="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> protected DeltaEntryScope(WriterState state, ODataItem entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, entry, navigationSource, entityType, selectedProperties, odataUri) { Debug.Assert(entry != null, "entry != null"); Debug.Assert( state == WriterState.DeltaEntry && entry is ODataEntry || state == WriterState.DeltaDeletedEntry && entry is ODataDeltaDeletedEntry, "entry must be either DeltaEntry or DeltaDeletedEntry."); Debug.Assert(writerBehavior != null, "writerBehavior != null"); this.duplicatePropertyNamesChecker = new DuplicatePropertyNamesChecker(writerBehavior.AllowDuplicatePropertyNames, /*writingResponse*/ true); this.serializationInfo = 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 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); }
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); }
public ODataFeedAndEntrySerializationInfoTests() { this.testSubject = new ODataFeedAndEntrySerializationInfo(); }
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)); }
/// <summary> /// Constructor to create a new entry scope. /// </summary> /// <param name="state">The writer state of the scope to create.</param> /// <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="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> internal JsonLightDeltaEntryScope(WriterState state, ODataItem entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(state, entry, serializationInfo, navigationSource, entityType, writerBehavior, selectedProperties, odataUri) { }
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> /// 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> internal AtomEntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri) : base(entry, serializationInfo, navigationSource, entityType, skipWriting, writingResponse, writerBehavior, selectedProperties, odataUri) { }
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); }
/// <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 JsonLightEntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri, bool enableValidation) : base(entry, serializationInfo, navigationSource, entityType, skipWriting, writingResponse, writerBehavior, selectedProperties, odataUri, enableValidation) { }
/// <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; }
/// <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; }
/// <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="entitySet">The entity set 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> internal AtomEntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntitySet entitySet, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties) : base(entry, serializationInfo, entitySet, entityType, skipWriting, writingResponse, writerBehavior, selectedProperties) { DebugUtils.CheckNoExternalCallers(); }