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 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> /// Place where derived writers can perform custom steps before the entry is writen, at the begining of WriteStartEntryImplementation. /// </summary> /// <param name="entry">Entry to write.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> protected override void PrepareEntryForWriteStart(ODataEntry entry, ODataFeedAndEntryTypeContext typeContext, SelectedPropertiesNode selectedProperties) { if (this.jsonLightOutputContext.MessageWriterSettings.AutoComputePayloadMetadataInJson) { EntryScope entryScope = (EntryScope)this.CurrentScope; Debug.Assert(entryScope != null, "entryScope != null"); ODataEntityMetadataBuilder builder = this.jsonLightOutputContext.MetadataLevel.CreateEntityMetadataBuilder( entry, typeContext, entryScope.SerializationInfo, entryScope.EntityType, selectedProperties, this.jsonLightOutputContext.WritingResponse, this.jsonLightOutputContext.MessageWriterSettings.AutoGeneratedUrlsShouldPutKeyValueInDedicatedSegment); this.jsonLightOutputContext.MetadataLevel.InjectMetadataBuilder(entry, builder); } }
/// <summary> /// Creates the metadata URI for a feed or entry. /// </summary> /// <param name="metadataDocumentUri">The non-null, absolute metadata document URI.</param> /// <param name="model">The Edm model instance.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="isEntry">true if the metadata URI is built for an entry, false if the metadata URI is built for a feed.</param> /// <param name="writingResponse">true if the metadata URI is for a response payload, false if the metadata URI is for a request payload.</param> /// <returns>Returns the metadata URI for the feed or entry.</returns> private static Uri CreateFeedOrEntryMetadataUri( ODataMetadataDocumentUri metadataDocumentUri, IEdmModel model, ODataFeedAndEntryTypeContext typeContext, bool isEntry, bool writingResponse) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(metadataDocumentUri != null, "metadataDocumentUri != null"); Debug.Assert(model != null, "model != null"); Debug.Assert(typeContext != null, "typeContext != null"); string typecast = typeContext.EntitySetElementTypeName == typeContext.ExpectedEntityTypeName ? null : typeContext.ExpectedEntityTypeName; Uri metadataUri = CreateEntityContainerElementMetadataUri(metadataDocumentUri, typeContext.EntitySetName, typecast, /*navigationPropertyName*/ null, /*appendItemSelector*/ isEntry); Debug.Assert(metadataUri != null || !writingResponse, "metadataUri != null || !writingResponse -- metadataUri cannot be null when writing a response payload."); return(metadataUri); }
public void ShouldWriteIfSerializationInfoWithoutNavigationSourceButUnknownSetOnFeedResponse() { this.CreateFeedContextUri(ODataFeedAndEntryTypeContext.Create( serializationInfo: new ODataFeedAndEntrySerializationInfo() { ExpectedTypeName = "NS.Type", IsFromCollection = true, NavigationSourceEntityTypeName = "NS.Type", NavigationSourceKind = EdmNavigationSourceKind.UnknownEntitySet, NavigationSourceName = null }, navigationSource: null, navigationSourceEntityType: null, expectedEntityType: null, model: EdmCoreModel.Instance, throwIfMissingTypeInfo: true), isResponse: true); }
/// <summary> /// Gets an entity metadata builder for the given entry. /// </summary> /// <param name="entryState">Entry state to use as reference for information needed by the builder.</param> /// <returns>An entity metadata builder.</returns> public ODataEntityMetadataBuilder GetEntityMetadataBuilderForReader(IODataJsonLightReaderEntryState entryState) { Debug.Assert(entryState != null, "entry != null"); // Only apply the conventional template builder on response. On a request we would only report what's on the wire. if (entryState.MetadataBuilder == null) { ODataEntry entry = entryState.Entry; if (this.isResponse) { ODataTypeAnnotation typeAnnotation = entry.GetAnnotation <ODataTypeAnnotation>(); Debug.Assert(typeAnnotation != null, "The JSON light reader should have already set the ODataTypeAnnotation."); IEdmEntitySet entitySet = typeAnnotation.EntitySet; IEdmEntityType entitySetElementType = this.edmTypeResolver.GetElementType(entitySet); IODataFeedAndEntryTypeContext typeContext = ODataFeedAndEntryTypeContext.Create( /*serializationInfo*/ null, entitySet, entitySetElementType, entryState.EntityType, this.model, /*throwIfMissingTypeInfo*/ true); IODataEntryMetadataContext entryMetadataContext = ODataEntryMetadataContext.Create( entry, typeContext, /*serializationInfo*/ null, (IEdmEntityType)entry.GetEdmType().Definition, this, entryState.SelectedProperties); UrlConvention urlConvention = UrlConvention.ForUserSettingAndTypeContext(/*keyAsSegment*/ null, typeContext); ODataConventionalUriBuilder uriBuilder = new ODataConventionalUriBuilder(this.ServiceBaseUri, urlConvention); entryState.MetadataBuilder = new ODataConventionalEntityMetadataBuilder(entryMetadataContext, this, uriBuilder); } else { entryState.MetadataBuilder = new NoOpEntityMetadataBuilder(entry); } } return(entryState.MetadataBuilder); }
/// <summary> /// Place where derived writers can perform custom steps before the entry is writen, at the begining of WriteStartEntryImplementation. /// </summary> /// <param name="entry">Entry to write.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> protected virtual void PrepareEntryForWriteStart(ODataEntry entry, ODataFeedAndEntryTypeContext typeContext, SelectedPropertiesNode selectedProperties) { // No-op Atom and Verbose JSON. The JSON Light writer will override this method and inject the appropriate metadata builder // into the entry before writing. // When we support AutoComputePayloadMetadata for all formats in the future, we can inject the metadata builder in here and // remove virtual from this method. }
/// <summary> /// Place where derived writers can perform custom steps before the entry is writen, at the begining of WriteStartEntryImplementation. /// </summary> /// <param name="entry">Entry to write.</param> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry or feed.</param> /// <param name="selectedProperties">The selected properties of this scope.</param> protected override void PrepareEntryForWriteStart(ODataEntry entry, ODataFeedAndEntryTypeContext typeContext, SelectedPropertiesNode selectedProperties) { if (this.jsonLightOutputContext.MessageWriterSettings.AutoComputePayloadMetadataInJson) { EntryScope entryScope = (EntryScope)this.CurrentScope; Debug.Assert(entryScope != null, "entryScope != null"); ODataEntityMetadataBuilder builder = this.jsonLightOutputContext.MetadataLevel.CreateEntityMetadataBuilder( entry, typeContext, entryScope.SerializationInfo, entryScope.EntityType, selectedProperties, this.jsonLightOutputContext.WritingResponse, this.jsonLightOutputContext.MessageWriterSettings.UseKeyAsSegment, this.jsonLightOutputContext.MessageWriterSettings.ODataUri); if (builder is ODataConventionalEntityMetadataBuilder) { builder.ParentMetadataBuilder = this.FindParentEntryMetadataBuilder(); } this.jsonLightOutputContext.MetadataLevel.InjectMetadataBuilder(entry, builder); } }
/// <summary> /// Creates the metadata URI for an entry based on the entity set it belongs to. /// </summary> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="metadataUri">Returns the metadata URI for an entry based on the entity set it belongs to.</param> /// <returns>true if we have successfully built the metadata URI; false otherwise.</returns> internal abstract bool TryBuildEntryMetadataUri(ODataFeedAndEntryTypeContext typeContext, out Uri metadataUri);
/// <summary> /// Tries to writes the context URI property for a feed into the payload if one is available. /// </summary> /// <param name="typeContext">The context object to answer basic questions regarding the type of the feed.</param> internal void TryWriteFeedContextUri(ODataFeedAndEntryTypeContext typeContext) { ODataUri odataUri = this.AtomOutputContext.MessageWriterSettings.ODataUri; this.WriteContextUriProperty(this.contextUriBuilder.BuildContextUri(ODataPayloadKind.Feed, ODataContextUrlInfo.Create(typeContext, /* isSingle */ false, odataUri))); }
private void InitializeTypeContext() { this.responseCityTypeContextWithoutSerializationInfo = ODataFeedAndEntryTypeContext.Create( /*serializationInfo*/null, this.citySet, this.cityType, this.cityType, this.edmModel, throwIfMissingTypeInfo: true); this.responseCapitolCityTypeContextWithoutSerializationInfo = ODataFeedAndEntryTypeContext.Create( /*serializationInfo*/null, this.citySet, this.cityType, this.capitolCityType, this.edmModel, throwIfMissingTypeInfo: true); }
/// <summary> /// Tries to writes the context URI property for a feed into the payload if one is available. /// </summary> /// <param name="typeContext">The context object to answer basic questions regarding the type of the feed.</param> /// <returns>The contextUrlInfo, if the context URI was successfully written.</returns> internal ODataContextUrlInfo WriteFeedContextUri(ODataFeedAndEntryTypeContext typeContext) { ODataUri odataUri = this.JsonLightOutputContext.MessageWriterSettings.ODataUri; return(this.WriteContextUriProperty(ODataPayloadKind.Feed, () => ODataContextUrlInfo.Create(typeContext, /* isSingle */ false, odataUri))); }
/// <summary> /// Create ODataContextUrlInfo from ODataFeedAndEntryTypeContext /// </summary> /// <param name="typeContext">The ODataFeedAndEntryTypeContext to be used.</param> /// <param name="isSingle">Whether target is single item.</param> /// <param name="odataUri">The odata uri info for current query.</param> /// <returns>The generated ODataContextUrlInfo.</returns> internal static ODataContextUrlInfo Create(ODataFeedAndEntryTypeContext typeContext, bool isSingle, ODataUri odataUri = null) { Debug.Assert(typeContext != null, "typeContext != null"); return new ODataContextUrlInfo() { isContained = typeContext.NavigationSourceKind == EdmNavigationSourceKind.ContainedEntitySet, IsUnknownEntitySet = typeContext.NavigationSourceKind == EdmNavigationSourceKind.UnknownEntitySet, navigationSource = typeContext.NavigationSourceName, TypeCast = typeContext.NavigationSourceEntityTypeName == typeContext.ExpectedEntityTypeName ? null : typeContext.ExpectedEntityTypeName, TypeName = typeContext.NavigationSourceFullTypeName, IncludeFragmentItemSelector = isSingle && typeContext.NavigationSourceKind != EdmNavigationSourceKind.Singleton, odataUri = odataUri }; }
public void ShouldCreateBaseClassWhenSerializationInfoAndUserModelAreBothMissingAndThrowIfMissingTypeInfoIsFalse() { var typeContext = ODataFeedAndEntryTypeContext.Create(serializationInfo: null, navigationSource: null, navigationSourceEntityType: null, expectedEntityType: null, model: EdmCoreModel.Instance, throwIfMissingTypeInfo: false); typeContext.Should().BeOfType <ODataFeedAndEntryTypeContext>(); }
/// <summary> /// Tries to writes the context URI property for delta entry/feed/link into the payload if one is available. /// </summary> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="kind">The delta kind to write.</param> /// <param name="parentContextUrlInfo">The parent contextUrlInfo.</param> /// <returns>The created context uri info.</returns> internal ODataContextUrlInfo WriteDeltaContextUri(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind, ODataContextUrlInfo parentContextUrlInfo = null) { ODataUri odataUri = this.JsonLightOutputContext.MessageWriterSettings.ODataUri; return this.WriteContextUriProperty(ODataPayloadKind.Delta, () => ODataContextUrlInfo.Create(typeContext, kind, odataUri), parentContextUrlInfo); }
public void ShouldNotIncludeFragmentItemSelectorOnSingleton() { var singletonTypeContextWithModel = ODataFeedAndEntryTypeContext.Create(/*serializationInfo*/ null, this.singletonCity, this.cityType, this.cityType, this.edmModel, throwIfMissingTypeInfo: true); this.CreateEntryContextUri(singletonTypeContextWithModel).OriginalString.Should().Be(BuildExpectedContextUri("#SingletonCity", false)); }
private Uri CreateDeltaResponseContextUri(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind) { ODataContextUrlInfo info = ODataContextUrlInfo.Create(typeContext, kind); Uri contextUrl = this.responseContextUriBuilder.BuildContextUri(ODataPayloadKind.Delta, info); contextUrl.Should().NotBeNull(); return contextUrl; }
private Uri CreateEntryContextUri(ODataFeedAndEntryTypeContext typeContext, bool isResponse = true) { ODataContextUrlInfo info = ODataContextUrlInfo.Create(typeContext, true); Uri contextUrl = isResponse ? this.responseContextUriBuilder.BuildContextUri(ODataPayloadKind.Entry, info) : this.requestContextUriBuilder.BuildContextUri(ODataPayloadKind.Entry, info); return contextUrl; }
/// <summary> /// Gets or creates the type context to answer basic questions regarding the type info of the entry. /// </summary> /// <param name="model">The Edm model to use.</param> /// <param name="writingResponse">Whether writing Json payload. Should always be true.</param> /// <returns>The type context to answer basic questions regarding the type info of the entry.</returns> public ODataFeedAndEntryTypeContext GetOrCreateTypeContext(IEdmModel model, bool writingResponse = true) { if (this.typeContext == null) { this.typeContext = ODataFeedAndEntryTypeContext.Create( this.serializationInfo, this.NavigationSource, EdmTypeWriterResolver.Instance.GetElementType(this.NavigationSource), this.fakeEntityType, model, writingResponse); } return this.typeContext; }
/// <summary> /// Creates the metadata URI for an entry based on the entity set it belongs to. /// </summary> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="metadataUri">Returns the metadata URI for an entry based on the entity set it belongs to.</param> /// <returns>true if we have successfully built the metadata URI; false otherwise.</returns> internal override bool TryBuildEntryMetadataUri(ODataFeedAndEntryTypeContext typeContext, out Uri metadataUri) { DebugUtils.CheckNoExternalCallers(); metadataUri = CreateFeedOrEntryMetadataUri(this.metadataDocumentUri, this.model, typeContext, /*isEntry*/ true, this.writingResponse); return(metadataUri != null); }
public void ShouldCreateBaseClassWhenEntitySetIsGivenButModelIsNotUserModel() { var typeContext = ODataFeedAndEntryTypeContext.Create(/*serializationInfo*/ null, EntitySet, EntitySetElementType, ExpectedEntityType, EdmCoreModel.Instance, throwIfMissingTypeInfo: true); typeContext.Should().BeOfType <ODataFeedAndEntryTypeContext>(); }
/// <summary> /// Tries to writes the context URI property for an entry into the payload if one is available. /// </summary> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="parentContextUrlInfo">The parent contextUrlInfo.</param> internal void WriteEntryContextUri(ODataFeedAndEntryTypeContext typeContext, ODataContextUrlInfo parentContextUrlInfo = null) { ODataUri odataUri = this.JsonLightOutputContext.MessageWriterSettings.ODataUri; this.WriteContextUriProperty(ODataPayloadKind.Entry, () => ODataContextUrlInfo.Create(typeContext, /* isSingle */ true, odataUri), parentContextUrlInfo); }
/// <summary> /// Creates the metadata URI for an entry based on the entity set it belongs to. /// </summary> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="metadataUri">Returns the metadata URI for an entry based on the entity set it belongs to.</param> /// <returns>true if we have successfully built the metadata URI; false otherwise.</returns> internal override bool TryBuildEntryMetadataUri(ODataFeedAndEntryTypeContext typeContext, out Uri metadataUri) { DebugUtils.CheckNoExternalCallers(); metadataUri = null; return(false); }
private void InitializeTypeContext() { this.responseCityTypeContextWithoutSerializationInfo = ODataFeedAndEntryTypeContext.Create(/*serializationInfo*/ null, this.citySet, this.cityType, this.cityType, this.edmModel, throwIfMissingTypeInfo: true); this.responseCapitolCityTypeContextWithoutSerializationInfo = ODataFeedAndEntryTypeContext.Create(/*serializationInfo*/ null, this.citySet, this.cityType, this.capitolCityType, this.edmModel, throwIfMissingTypeInfo: true); }
/// <summary> /// Tries to writes the context URI property for a feed into the payload if one is available. /// </summary> /// <param name="typeContext">The context object to answer basic questions regarding the type of the feed.</param> /// <returns>The contextUrlInfo, if the context URI was successfully written.</returns> internal ODataContextUrlInfo WriteFeedContextUri(ODataFeedAndEntryTypeContext typeContext) { ODataUri odataUri = this.JsonLightOutputContext.MessageWriterSettings.ODataUri; return this.WriteContextUriProperty(ODataPayloadKind.Feed, () => ODataContextUrlInfo.Create(typeContext, /* isSingle */ false, odataUri)); }
/// <summary> /// Create contextUrlInfo for delta /// </summary> /// <param name="typeContext">The ODataFeedAndEntryTypeContext to be used.</param> /// <param name="kind">The delta kind.</param> /// <param name="odataUri">The odata uri info for current query.</param> /// <returns>The generated ODataContextUrlInfo.</returns> internal static ODataContextUrlInfo Create(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind, ODataUri odataUri = null) { Debug.Assert(typeContext != null, "typeContext != null"); ODataContextUrlInfo contextUriInfo = new ODataContextUrlInfo() { isContained = typeContext.NavigationSourceKind == EdmNavigationSourceKind.ContainedEntitySet, IsUnknownEntitySet = typeContext.NavigationSourceKind == EdmNavigationSourceKind.UnknownEntitySet, navigationSource = typeContext.NavigationSourceName, TypeCast = typeContext.NavigationSourceEntityTypeName == typeContext.ExpectedEntityTypeName ? null : typeContext.ExpectedEntityTypeName, TypeName = typeContext.NavigationSourceEntityTypeName, IncludeFragmentItemSelector = kind == ODataDeltaKind.Entry && typeContext.NavigationSourceKind != EdmNavigationSourceKind.Singleton, DeltaKind = kind, }; // Only use odata uri in with model case. if (typeContext is ODataFeedAndEntryTypeContext.ODataFeedAndEntryTypeContextWithModel) { contextUriInfo.odataUri = odataUri; } return contextUriInfo; }
/// <summary> /// Tries to writes the context URI property for delta entry/feed/link into the payload if one is available. /// </summary> /// <param name="typeContext">The context object to answer basic questions regarding the type of the entry.</param> /// <param name="kind">The delta kind to write.</param> /// <param name="parentContextUrlInfo">The parent contextUrlInfo.</param> /// <returns>The created context uri info.</returns> internal ODataContextUrlInfo WriteDeltaContextUri(ODataFeedAndEntryTypeContext typeContext, ODataDeltaKind kind, ODataContextUrlInfo parentContextUrlInfo = null) { ODataUri odataUri = this.JsonLightOutputContext.MessageWriterSettings.ODataUri; return(this.WriteContextUriProperty(ODataPayloadKind.Delta, () => ODataContextUrlInfo.Create(typeContext, kind, odataUri), parentContextUrlInfo)); }