/// <summary> /// Creates the collection of <see cref="ODataNavigationLink"/>s to be written while writing this entity. /// </summary> /// <param name="entityInstanceContext">The context for the entity instance being written.</param> /// <param name="writeContext">The serializer write context.</param> /// <returns>The collection of navigation links to be written.</returns> public virtual IEnumerable <ODataNavigationLink> CreateNavigationLinks(EntityInstanceContext entityInstanceContext, ODataSerializerContext writeContext) { if (writeContext == null) { throw Error.ArgumentNull("writeContext"); } foreach (IEdmNavigationProperty navProperty in EntityType.NavigationProperties()) { IEdmTypeReference propertyType = navProperty.Type; if (writeContext.EntitySet != null) { IEdmModel model = writeContext.Model; EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(writeContext.EntitySet); Uri navigationUrl = linkBuilder.BuildNavigationLink(entityInstanceContext, navProperty, writeContext.MetadataLevel); ODataNavigationLink navigationLink = new ODataNavigationLink { IsCollection = propertyType.IsCollection(), Name = navProperty.Name, }; if (navigationUrl != null) { navigationLink.Url = navigationUrl; } yield return(navigationLink); } } }
public void NavigationLinksGenerationConvention_GeneratesLinksWithoutCast_ForBaseProperties() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet <SportBike>("vehicles"); builder.EntitySet <Manufacturer>("manufacturers"); IEdmModel model = builder.GetEdmModel(); IEdmEntitySet vehiclesEdmEntitySet = model.EntityContainers().Single().FindEntitySet("vehicles"); IEdmEntityType sportbikeType = model.AssertHasEntityType(typeof(SportBike)); IEdmNavigationProperty motorcycleManufacturerProperty = sportbikeType.AssertHasNavigationProperty(model, "Manufacturer", typeof(MotorcycleManufacturer), isNullable: true, multiplicity: EdmMultiplicity.ZeroOrOne); HttpConfiguration configuration = new HttpConfiguration(); string routeName = "Route"; configuration.Routes.MapODataServiceRoute(routeName, null, model); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost"); request.SetConfiguration(configuration); request.ODataProperties().RouteName = routeName; EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet); var serializerContext = new ODataSerializerContext { Model = model, EntitySet = vehiclesEdmEntitySet, Url = request.GetUrlHelper() }; var entityContext = new EntityInstanceContext(serializerContext, sportbikeType.AsReference(), new SportBike { Model = 2009, Name = "Ninja" }); Uri uri = linkBuilder.BuildNavigationLink(entityContext, motorcycleManufacturerProperty, ODataMetadataLevel.Default); Assert.Equal("http://localhost/vehicles(Model=2009,Name='Ninja')/Manufacturer", uri.AbsoluteUri); }
/// <summary> /// Creates the <see cref="ODataNavigationLink"/> to be written while writing this entity. /// </summary> /// <param name="navigationProperty">The navigation property for which the navigation link is being created.</param> /// <param name="entityInstanceContext">The context for the entity instance being written.</param> /// <returns>The navigation link to be written.</returns> public virtual ODataNavigationLink CreateNavigationLink(IEdmNavigationProperty navigationProperty, EntityInstanceContext entityInstanceContext) { if (navigationProperty == null) { throw Error.ArgumentNull("navigationProperty"); } if (entityInstanceContext == null) { throw Error.ArgumentNull("entityInstanceContext"); } ODataSerializerContext writeContext = entityInstanceContext.SerializerContext; ODataNavigationLink navigationLink = null; if (writeContext.EntitySet != null) { IEdmTypeReference propertyType = navigationProperty.Type; IEdmModel model = writeContext.Model; EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(writeContext.EntitySet); Uri navigationUrl = linkBuilder.BuildNavigationLink(entityInstanceContext, navigationProperty, writeContext.MetadataLevel); navigationLink = new ODataNavigationLink { IsCollection = propertyType.IsCollection(), Name = navigationProperty.Name, }; if (navigationUrl != null) { navigationLink.Url = navigationUrl; } } return(navigationLink); }
public void NavigationLinksGenerationConvention_GeneratesLinksWithCast_ForDerivedProperties() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet <Vehicle>("vehicles"); builder.EntitySet <Manufacturer>("manufacturers"); IEdmModel model = builder.GetEdmModel(); IEdmEntitySet vehiclesEdmEntitySet = model.EntityContainers().Single().FindEntitySet("vehicles"); IEdmEntityType carType = model.AssertHasEntityType(typeof(Car)); IEdmNavigationProperty carManufacturerProperty = carType.AssertHasNavigationProperty(model, "Manufacturer", typeof(CarManufacturer), isNullable: true, multiplicity: EdmMultiplicity.ZeroOrOne); HttpConfiguration configuration = new HttpConfiguration(); string routeName = "Route"; configuration.Routes.MapODataRoute(routeName, null, model); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost"); request.SetConfiguration(configuration); request.SetODataRouteName(routeName); EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet); var serializerContext = new ODataSerializerContext { Model = model, EntitySet = vehiclesEdmEntitySet, Url = request.GetUrlHelper() }; var entityContext = new EntityInstanceContext(serializerContext, carType.AsReference(), new Car { Model = 2009, Name = "Accord" }); Uri uri = linkBuilder.BuildNavigationLink(entityContext, carManufacturerProperty, ODataMetadataLevel.Default); Assert.Equal("http://localhost/vehicles(Model=2009,Name='Accord')/System.Web.Http.OData.Builder.TestModels.Car/Manufacturer", uri.AbsoluteUri); }
/// <summary> /// Creates the <see cref="ODataEntry"/> to be written while writing this entity. /// </summary> /// <param name="selectExpandNode">The <see cref="SelectExpandNode"/> describing the response graph.</param> /// <param name="entityInstanceContext">The context for the entity instance being written.</param> /// <returns>The created <see cref="ODataEntry"/>.</returns> public virtual ODataEntry CreateEntry(SelectExpandNode selectExpandNode, EntityInstanceContext entityInstanceContext) { if (selectExpandNode == null) { throw Error.ArgumentNull("selectExpandNode"); } if (entityInstanceContext == null) { throw Error.ArgumentNull("entityInstanceContext"); } string typeName = entityInstanceContext.EntityType.FullName(); ODataEntry entry = new ODataEntry { TypeName = typeName, Properties = CreateStructuralPropertyBag(selectExpandNode.SelectedStructuralProperties, entityInstanceContext), Actions = CreateODataActions(selectExpandNode.SelectedActions, entityInstanceContext) }; IEdmEntityType pathType = GetODataPathType(entityInstanceContext.SerializerContext); AddTypeNameAnnotationAsNeeded(entry, pathType, entityInstanceContext.SerializerContext.MetadataLevel); if (entityInstanceContext.EntitySet != null) { IEdmModel model = entityInstanceContext.SerializerContext.Model; EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(entityInstanceContext.EntitySet); EntitySelfLinks selfLinks = linkBuilder.BuildEntitySelfLinks(entityInstanceContext, entityInstanceContext.SerializerContext.MetadataLevel); if (selfLinks.IdLink != null) { entry.Id = new Uri(selfLinks.IdLink); } if (selfLinks.ReadLink != null) { entry.ReadLink = selfLinks.ReadLink; } if (selfLinks.EditLink != null) { entry.EditLink = selfLinks.EditLink; } string etag = CreateETag(entityInstanceContext); if (etag != null) { entry.ETag = etag; } } return(entry); }
/// <summary> /// Create the <see cref="ODataFeed"/> to be written for the given feed instance. /// </summary> /// <param name="feedInstance">The instance representing the feed being written.</param> /// <param name="writeContext">The serializer context.</param> /// <returns>The created <see cref="ODataFeed"/> object.</returns> public virtual ODataFeed CreateODataFeed(IEnumerable feedInstance, ODataSerializerContext writeContext) { ODataFeed feed = new ODataFeed(); if (writeContext.EntitySet != null) { IEdmModel model = writeContext.Model; EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(writeContext.EntitySet); FeedContext feedContext = new FeedContext { Request = writeContext.Request, EntitySet = writeContext.EntitySet, Url = writeContext.Url, FeedInstance = feedInstance }; Uri feedSelfLink = linkBuilder.BuildFeedSelfLink(feedContext); if (feedSelfLink != null) { feed.SetAnnotation(new AtomFeedMetadata() { SelfLink = new AtomLinkMetadata() { Relation = "self", Href = feedSelfLink } }); } } // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ? feed.Id = "http://schemas.datacontract.org/2004/07/" + EntityCollectionType.FullName(); // If we have more OData format specific information apply it now. PageResult odataFeedAnnotations = feedInstance as PageResult; if (odataFeedAnnotations != null) { feed.Count = odataFeedAnnotations.Count; feed.NextPageLink = odataFeedAnnotations.NextPageLink; } else if (writeContext.Request != null) { feed.NextPageLink = writeContext.Request.GetNextPageLink(); long?inlineCount = writeContext.Request.GetInlineCount(); if (inlineCount.HasValue) { feed.Count = inlineCount.Value; } } return(feed); }
public void GetEntitySetLinkBuilder_After_SetEntitySetLinkBuilder() { // Arrange IEdmModel model = new EdmModel(); EdmEntityContainer container = new EdmEntityContainer("NS", "Container"); EdmEntityType entityType = new EdmEntityType("NS", "Entity"); IEdmEntitySet entitySet = new EdmEntitySet(container, "EntitySet", entityType); EntitySetLinkBuilderAnnotation entitySetLinkBuilder = new EntitySetLinkBuilderAnnotation(); // Act model.SetEntitySetLinkBuilder(entitySet, entitySetLinkBuilder); var result = model.GetEntitySetLinkBuilder(entitySet); // Assert Assert.Same(entitySetLinkBuilder, result); }
private static Uri GetNestedNextPageLink(ODataSerializerContext writeContext, int pageSize) { Contract.Assert(writeContext.ExpandedEntity != null); IEdmEntitySet sourceEntitySet = writeContext.ExpandedEntity.EntitySet; EntitySetLinkBuilderAnnotation linkBuilder = writeContext.Model.GetEntitySetLinkBuilder(sourceEntitySet); Uri navigationLink = linkBuilder.BuildNavigationLink(writeContext.ExpandedEntity, writeContext.NavigationProperty, ODataMetadataLevel.Default); if (navigationLink != null) { return(ODataQueryOptions.GetNextPageLink(navigationLink, pageSize)); } return(null); }
public static EntitySetLinkBuilderAnnotation GetEntitySetLinkBuilder(this IEdmModel model, IEdmEntitySet entitySet) { if (model == null) { throw Error.ArgumentNull("model"); } EntitySetLinkBuilderAnnotation annotation = model.GetAnnotationValue <EntitySetLinkBuilderAnnotation>(entitySet); if (annotation == null) { // construct and set an entity set link builder that follows OData URL conventions. annotation = new EntitySetLinkBuilderAnnotation(entitySet, model); model.SetEntitySetLinkBuilder(entitySet, annotation); } return(annotation); }
internal Uri GenerateLocationHeader() { EntityInstanceContext entityContext = CreateEntityInstanceContext(Request, Entity); Contract.Assert(entityContext != null); EntitySetLinkBuilderAnnotation linkBuilder = entityContext.EdmModel.GetEntitySetLinkBuilder(entityContext.EntitySet); Contract.Assert(linkBuilder != null); string idLink = linkBuilder.BuildIdLink(entityContext, ODataMetadataLevel.Default); Uri editLink = linkBuilder.BuildEditLink(entityContext, ODataMetadataLevel.Default, idLink); if (editLink == null) { throw Error.InvalidOperation(SRResources.EditLinkNullForLocationHeader, entityContext.EntitySet.Name); } return(editLink); }
public void SelfLinksGenerationConvention_Uses_GetByIdWithCast_IfDerivedTypeHasNavigationProperty() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); var vehicles = builder.EntitySet <Vehicle>("vehicles"); IEdmModel model = builder.GetEdmModel(); IEdmEntitySet vehiclesEdmEntitySet = model.EntityContainers().Single().EntitySets().Single(); IEdmEntityType carType = model.AssertHasEntityType(typeof(Car)); HttpRequestMessage request = GetODataRequest(model); EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet); var serializerContext = new ODataSerializerContext { Model = model, EntitySet = vehiclesEdmEntitySet, Url = request.GetUrlHelper() }; var entityContext = new EntityInstanceContext(serializerContext, carType.AsReference(), new Car { Model = 2009, Name = "Accord" }); EntitySelfLinks selfLinks = linkBuilder.BuildEntitySelfLinks(entityContext, ODataMetadataLevel.Default); Assert.Equal("http://localhost/vehicles(Model=2009,Name='Accord')/System.Web.Http.OData.Builder.TestModels.Car", selfLinks.IdLink); }
public void SelfLinksGenerationConvention_Uses_GetByIdWithoutCast_IfDerivedTypeDoesnotHaveNavigationProperty() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); var motorcycles = builder.EntitySet <Motorcycle>("motorcycles"); IEdmModel model = builder.GetEdmModel(); IEdmEntitySet vehiclesEdmEntitySet = model.EntityContainers().Single().EntitySets().Single(); IEdmEntityType sportbikeType = model.AssertHasEntityType(typeof(SportBike)); HttpRequestMessage request = GetODataRequest(model); EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet); var serializerContext = new ODataSerializerContext { Model = model, EntitySet = vehiclesEdmEntitySet, Url = request.GetUrlHelper() }; var entityContext = new EntityInstanceContext(serializerContext, sportbikeType.AsReference(), new SportBike { Model = 2009, Name = "Ninja" }); EntitySelfLinks selfLinks = linkBuilder.BuildEntitySelfLinks(entityContext, ODataMetadataLevel.Default); Assert.Equal("http://localhost/motorcycles(Model=2009,Name='Ninja')", selfLinks.IdLink); }
/// <summary> /// Creates the <see cref="ODataEntry"/> to be written while writing this entity. /// </summary> /// <param name="entityInstanceContext">The context for the entity instance being written.</param> /// <param name="writeContext">The serializer write context.</param> /// <returns>The created <see cref="ODataEntry"/>.</returns> public virtual ODataEntry CreateEntry(EntityInstanceContext entityInstanceContext, ODataSerializerContext writeContext) { string typeName = EntityType.FullName(); ODataEntry entry = new ODataEntry { TypeName = typeName, Properties = CreateStructuralPropertyBag(entityInstanceContext, writeContext), Actions = CreateODataActions(entityInstanceContext, writeContext) }; AddTypeNameAnnotationAsNeeded(entry, writeContext.EntitySet, writeContext.MetadataLevel); if (writeContext.EntitySet != null) { IEdmModel model = writeContext.Model; EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(writeContext.EntitySet); EntitySelfLinks selfLinks = linkBuilder.BuildEntitySelfLinks(entityInstanceContext, writeContext.MetadataLevel); if (selfLinks.IdLink != null) { entry.Id = selfLinks.IdLink; } if (selfLinks.ReadLink != null) { entry.ReadLink = selfLinks.ReadLink; } if (selfLinks.EditLink != null) { entry.EditLink = selfLinks.EditLink; } } return(entry); }
public void SelfLinksGenerationConvention_Uses_GetByIdWithoutCast_IfDerivedTypeDoesnotHaveNavigationProperty() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); var motorcycles = builder.EntitySet <Motorcycle>("motorcycles"); IEdmModel model = builder.GetEdmModel(); IEdmEntitySet vehiclesEdmEntitySet = model.EntityContainers().Single().EntitySets().Single(); IEdmEntityType sportbikeType = model.AssertHasEntityType(typeof(SportBike)); HttpConfiguration configuration = new HttpConfiguration(); string routeName = "Route"; configuration.Routes.MapODataRoute(routeName, null, model); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost"); request.SetConfiguration(configuration); request.SetODataRouteName(routeName); EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet); EntitySelfLinks selfLinks = linkBuilder.BuildEntitySelfLinks( new EntityInstanceContext() { EdmModel = model, EntitySet = vehiclesEdmEntitySet, EntityType = sportbikeType, Url = request.GetUrlHelper(), EntityInstance = new Car { Model = 2009, Name = "Ninja" } }, ODataMetadataLevel.Default); Assert.Equal("http://localhost/motorcycles(Model=2009,Name='Ninja')", selfLinks.IdLink); }
public void SelfLinksGenerationConvention_Uses_GetByIdWithCast_IfDerivedTypeHasNavigationProperty() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); var vehicles = builder.EntitySet <Vehicle>("vehicles"); IEdmModel model = builder.GetEdmModel(); IEdmEntitySet vehiclesEdmEntitySet = model.EntityContainers().Single().EntitySets().Single(); IEdmEntityType carType = model.AssertHasEntityType(typeof(Car)); HttpConfiguration configuration = new HttpConfiguration(); string routeName = "Route"; configuration.Routes.MapODataRoute(routeName, null, model); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost"); request.SetConfiguration(configuration); request.SetODataRouteName(routeName); EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet); EntitySelfLinks selfLinks = linkBuilder.BuildEntitySelfLinks( new EntityInstanceContext() { EdmModel = model, EntitySet = vehiclesEdmEntitySet, EntityType = carType, Url = request.GetUrlHelper(), EntityInstance = new Car { Model = 2009, Name = "Accord" } }, ODataMetadataLevel.Default); Assert.Equal("http://localhost/vehicles(Model=2009,Name='Accord')/System.Web.Http.OData.Builder.TestModels.Car", selfLinks.IdLink); }
/// <summary> /// Create the <see cref="ODataFeed"/> to be written for the given feed instance. /// </summary> /// <param name="feedInstance">The instance representing the feed being written.</param> /// <param name="feedType">The EDM type of the feed being written.</param> /// <param name="writeContext">The serializer context.</param> /// <returns>The created <see cref="ODataFeed"/> object.</returns> public virtual ODataFeed CreateODataFeed(IEnumerable feedInstance, IEdmCollectionTypeReference feedType, ODataSerializerContext writeContext) { ODataFeed feed = new ODataFeed(); if (writeContext.EntitySet != null) { IEdmModel model = writeContext.Model; EntitySetLinkBuilderAnnotation linkBuilder = model.GetEntitySetLinkBuilder(writeContext.EntitySet); FeedContext feedContext = new FeedContext { Request = writeContext.Request, RequestContext = writeContext.RequestContext, EntitySet = writeContext.EntitySet, Url = writeContext.Url, FeedInstance = feedInstance }; Uri feedSelfLink = linkBuilder.BuildFeedSelfLink(feedContext); if (feedSelfLink != null) { feed.SetAnnotation(new AtomFeedMetadata() { SelfLink = new AtomLinkMetadata() { Relation = "self", Href = feedSelfLink } }); } } // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ? feed.Id = "http://schemas.datacontract.org/2004/07/" + feedType.FullName(); if (writeContext.ExpandedEntity == null) { // If we have more OData format specific information apply it now, only if we are the root feed. PageResult odataFeedAnnotations = feedInstance as PageResult; if (odataFeedAnnotations != null) { feed.Count = odataFeedAnnotations.Count; feed.NextPageLink = odataFeedAnnotations.NextPageLink; } else if (writeContext.Request != null) { feed.NextPageLink = writeContext.Request.ODataProperties().NextLink; long?inlineCount = writeContext.Request.ODataProperties().TotalCount; if (inlineCount.HasValue) { feed.Count = inlineCount.Value; } } } else { // nested feed ITruncatedCollection truncatedCollection = feedInstance as ITruncatedCollection; if (truncatedCollection != null && truncatedCollection.IsTruncated) { feed.NextPageLink = GetNestedNextPageLink(writeContext, truncatedCollection.PageSize); } } return(feed); }
public static void SetEntitySetLinkBuilder(this IEdmModel model, IEdmEntitySet entitySet, EntitySetLinkBuilderAnnotation entitySetLinkBuilder) { if (model == null) { throw Error.ArgumentNull("model"); } model.SetAnnotationValue(entitySet, entitySetLinkBuilder); }