コード例 #1
0
        /// <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);
                }
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
        /// <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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
ファイル: CreatedODataResult.cs プロジェクト: tvdburgt/WebApi
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        /// <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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        /// <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);
        }
コード例 #17
0
        public static void SetEntitySetLinkBuilder(this IEdmModel model, IEdmEntitySet entitySet, EntitySetLinkBuilderAnnotation entitySetLinkBuilder)
        {
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            model.SetAnnotationValue(entitySet, entitySetLinkBuilder);
        }