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();

            configuration.Routes.MapHttpRoute(ODataRouteNames.GetById, "{controller}({id})");

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost");

            request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration;
            request.Properties[HttpPropertyKeys.HttpRouteDataKey]     = new HttpRouteData(new HttpRoute());

            IEntitySetLinkBuilder linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet);

            Uri uri = linkBuilder.BuildEditLink(
                new EntityInstanceContext(model, vehiclesEdmEntitySet, sportbikeType, request.GetUrlHelper(), new SportBike {
                Model = 2009, Name = "Ninja"
            }));

            Assert.Equal("http://localhost/motorcycles(Model=2009,Name='Ninja')", uri.AbsoluteUri);
        }
        public void SelfLinksGenerationConvention_Throws_If_RouteInCorrect()
        {
            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();

            configuration.Routes.MapHttpRoute(ODataRouteNames.GetById, "{Cntroller}({id})");

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost");

            request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration;
            request.Properties[HttpPropertyKeys.HttpRouteDataKey]     = new HttpRouteData(new HttpRoute());

            IEntitySetLinkBuilder linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet);

            Assert.Throws <InvalidOperationException>(
                () => linkBuilder.BuildEditLink(new EntityInstanceContext(model, vehiclesEdmEntitySet, sportbikeType, request.GetUrlHelper(), new SportBike {
                Model = 2009, Name = "Ninja"
            })),
                "EditLink generation failed. Check that you have the 'OData.GetById' route correctly registered.");
        }
        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();

            configuration.Routes.MapHttpRoute(ODataRouteNames.PropertyNavigationWithCast, "{controller}({parentid})/{entitytype}/{navigationproperty}");

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost");

            request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration;
            request.Properties[HttpPropertyKeys.HttpRouteDataKey]     = new HttpRouteData(new HttpRoute());

            IEntitySetLinkBuilder linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet);

            Uri uri = linkBuilder.BuildNavigationLink(
                new EntityInstanceContext(model, vehiclesEdmEntitySet, carType, request.GetUrlHelper(), new Car {
                Model = 2009, Name = "Accord"
            }),
                carManufacturerProperty);

            Assert.Equal("http://localhost/vehicles(Model=2009,Name='Accord')/System.Web.Http.OData.Builder.TestModels.Car/Manufacturer", uri.AbsoluteUri);
        }
        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();

            configuration.Routes.MapHttpRoute(ODataRouteNames.GetByIdWithCast, "{controller}({id})/{entitytype}");

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost");

            request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration;
            request.Properties[HttpPropertyKeys.HttpRouteDataKey]     = new HttpRouteData(new HttpRoute());

            IEntitySetLinkBuilder linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet);

            Uri uri = linkBuilder.BuildEditLink(
                new EntityInstanceContext(model, vehiclesEdmEntitySet, carType, request.GetUrlHelper(), new Car {
                Model = 2009, Name = "Accord"
            }));

            Assert.Equal("http://localhost/vehicles(Model=2009,Name='Accord')/System.Web.Http.OData.Builder.TestModels.Car", uri.AbsoluteUri);
        }
        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();

            configuration.Routes.MapHttpRoute(ODataRouteNames.PropertyNavigation, "{controller}({parentid})/{navigationproperty}");

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost");

            request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration;
            request.Properties[HttpPropertyKeys.HttpRouteDataKey]     = new HttpRouteData(new HttpRoute());

            IEntitySetLinkBuilder linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet);

            Uri uri = linkBuilder.BuildNavigationLink(
                new EntityInstanceContext(model, vehiclesEdmEntitySet, sportbikeType, request.GetUrlHelper(), new SportBike {
                Model = 2009, Name = "Ninja"
            }),
                motorcycleManufacturerProperty);

            Assert.Equal("http://localhost/vehicles(Model=2009,Name='Ninja')/Manufacturer", uri.AbsoluteUri);
        }
        internal static IEntitySetLinkBuilder GetEntitySetLinkBuilder(this IEdmModel model, IEdmEntitySet entitySet)
        {
            IEntitySetLinkBuilder annotation = model.GetAnnotationValue <IEntitySetLinkBuilder>(entitySet);

            if (annotation == null)
            {
                throw Error.NotSupported(SRResources.EntitySetHasNoBuildLinkAnnotation, entitySet.Name);
            }

            return(annotation);
        }
        private void WriteFeed(object graph, ODataWriter writer, ODataSerializerContext writeContext)
        {
            ODataSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(_edmCollectionType.ElementType());

            if (entrySerializer == null)
            {
                throw Error.NotSupported(SRResources.TypeCannotBeSerialized, _edmCollectionType.ElementType(), typeof(ODataMediaTypeFormatter).Name);
            }

            Contract.Assert(entrySerializer.ODataPayloadKind == ODataPayloadKind.Entry);

            IEnumerable enumerable = graph as IEnumerable; // Data to serialize

            if (enumerable != null)
            {
                ODataFeed feed = new ODataFeed();

                if (writeContext.EntitySet != null)
                {
                    IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);
                    Uri feedSelfLink = linkBuilder.BuildFeedSelfLink(new FeedContext(writeContext.EntitySet, writeContext.UrlHelper, graph));
                    if (feedSelfLink != null)
                    {
                        feed.SetAnnotation(new AtomFeedMetadata()
                        {
                            SelfLink = new AtomLinkMetadata()
                            {
                                Relation = SelfLinkRelation, Href = feedSelfLink
                            }
                        });
                    }
                }

                // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ?
                feed.Id = FeedNamespace + _edmCollectionType.FullName();

                // If we have more OData format specific information apply it now.
                ODataResult odataFeedAnnotations = graph as ODataResult;
                if (odataFeedAnnotations != null)
                {
                    feed.Count        = odataFeedAnnotations.Count;
                    feed.NextPageLink = odataFeedAnnotations.NextPageLink;
                }

                writer.WriteStart(feed);

                foreach (object entry in enumerable)
                {
                    entrySerializer.WriteObjectInline(entry, writer, writeContext);
                }

                writer.WriteEnd();
            }
        }
        private void WriteNavigationLinks(EntityInstanceContext context, ODataWriter writer, ODataSerializerWriteContext writeContext)
        {
            foreach (IEdmNavigationProperty navProperty in _edmEntityTypeReference.NavigationProperties())
            {
                IEdmTypeReference propertyType  = navProperty.Type;
                object            propertyValue = context.EntityInstance.GetType().GetProperty(navProperty.Name).GetValue(context.EntityInstance, index: null);

                if (writeContext.EntitySet != null)
                {
                    IEdmEntitySet         currentEntitySet = writeContext.EntitySet.FindNavigationTarget(navProperty);
                    IEntitySetLinkBuilder linkBuilder      = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);

                    ODataNavigationLink navigationLink = new ODataNavigationLink
                    {
                        IsCollection = propertyType.IsCollection(),
                        Name         = navProperty.Name,
                        Url          = linkBuilder.BuildNavigationLink(context, navProperty)
                    };

                    ODataQueryProjectionNode expandNode = null;
                    if (writeContext.CurrentProjectionNode != null)
                    {
                        expandNode = writeContext.CurrentProjectionNode.Expands.FirstOrDefault(p => p.Name == navProperty.Name);
                    }

                    if (expandNode != null && propertyValue != null)
                    {
                        writer.WriteStart(navigationLink);
                        ODataSerializer serializer = SerializerProvider.GetEdmTypeSerializer(propertyType);
                        if (serializer == null)
                        {
                            throw Error.NotSupported(SRResources.TypeCannotBeSerialized, navProperty.Type.FullName(), typeof(ODataMediaTypeFormatter).Name);
                        }

                        ODataSerializerWriteContext childWriteContext = new ODataSerializerWriteContext(writeContext.ResponseContext);
                        childWriteContext.UrlHelper             = writeContext.UrlHelper;
                        childWriteContext.EntitySet             = currentEntitySet;
                        childWriteContext.RootProjectionNode    = writeContext.RootProjectionNode;
                        childWriteContext.CurrentProjectionNode = expandNode;

                        serializer.WriteObjectInline(propertyValue, writer, childWriteContext);
                        writer.WriteEnd();
                    }
                    else if (!writeContext.IsRequest)
                    {
                        // delayed links cannot be written on requests
                        writer.WriteStart(navigationLink);
                        writer.WriteEnd();
                    }
                }
            }
        }
        private void WriteEntry(object graph, IEnumerable <ODataProperty> propertyBag, ODataWriter writer, ODataSerializerContext writeContext)
        {
            IEdmEntityType        entityType            = _edmEntityTypeReference.EntityDefinition();
            EntityInstanceContext entityInstanceContext = new EntityInstanceContext
            {
                EdmModel       = SerializerProvider.EdmModel,
                EntitySet      = writeContext.EntitySet,
                EntityType     = entityType,
                UrlHelper      = writeContext.UrlHelper,
                PathHandler    = writeContext.PathHandler,
                EntityInstance = graph,
                SkipExpensiveAvailabilityChecks = writeContext.SkipExpensiveAvailabilityChecks
            };

            ODataEntry entry = new ODataEntry
            {
                TypeName   = _edmEntityTypeReference.FullName(),
                Properties = propertyBag,
                Actions    = CreateActions(entityInstanceContext)
            };

            if (writeContext.EntitySet != null)
            {
                IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);

                string idLink = linkBuilder.BuildIdLink(entityInstanceContext);
                if (idLink != null)
                {
                    entry.Id = idLink;
                }

                Uri readLink = linkBuilder.BuildReadLink(entityInstanceContext);
                if (readLink != null)
                {
                    entry.ReadLink = readLink;
                }

                Uri editLink = linkBuilder.BuildEditLink(entityInstanceContext);
                if (editLink != null)
                {
                    entry.EditLink = editLink;
                }
            }

            writer.WriteStart(entry);
            WriteNavigationLinks(entityInstanceContext, writer, writeContext);
            writer.WriteEnd();
        }
        private void WriteNavigationLinks(EntityInstanceContext context, ODataWriter writer, ODataSerializerContext writeContext)
        {
            foreach (IEdmNavigationProperty navProperty in _edmEntityTypeReference.NavigationProperties())
            {
                IEdmTypeReference propertyType = navProperty.Type;

                if (writeContext.EntitySet != null)
                {
                    IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);

                    ODataNavigationLink navigationLink = new ODataNavigationLink
                    {
                        IsCollection = propertyType.IsCollection(),
                        Name         = navProperty.Name,
                        Url          = linkBuilder.BuildNavigationLink(context, navProperty)
                    };

                    writer.WriteStart(navigationLink);
                    writer.WriteEnd();
                }
            }
        }
        public void NavigationLinksGenerationConvention_GeneratesLinksWithoutCast_ForDeclaredProperties()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntitySet <Car>("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();

            configuration.EnableOData(model);

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost");

            request.Properties[HttpPropertyKeys.HttpConfigurationKey] = configuration;
            request.Properties[HttpPropertyKeys.HttpRouteDataKey]     = new HttpRouteData(new HttpRoute());

            IEntitySetLinkBuilder linkBuilder = model.GetEntitySetLinkBuilder(vehiclesEdmEntitySet);

            Uri uri = linkBuilder.BuildNavigationLink(
                new EntityInstanceContext()
            {
                EdmModel       = model,
                EntitySet      = vehiclesEdmEntitySet,
                EntityType     = carType,
                UrlHelper      = request.GetUrlHelper(),
                PathHandler    = new DefaultODataPathHandler(model),
                EntityInstance = new Car {
                    Model = 2009, Name = "Accord"
                }
            },
                carManufacturerProperty);

            Assert.Equal("http://localhost/vehicles(Model=2009,Name='Accord')/Manufacturer", uri.AbsoluteUri);
        }
        private void WriteEntry(object graph, IEnumerable <ODataProperty> propertyBag, ODataWriter writer, ODataSerializerContext writeContext)
        {
            IEdmEntityType        entityType            = _edmEntityTypeReference.EntityDefinition();
            EntityInstanceContext entityInstanceContext = new EntityInstanceContext(SerializerProvider.EdmModel, writeContext.EntitySet, entityType, writeContext.UrlHelper, graph);

            ODataEntry entry = new ODataEntry
            {
                TypeName   = _edmEntityTypeReference.FullName(),
                Properties = propertyBag,
            };

            if (writeContext.EntitySet != null)
            {
                IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);

                string idLink = linkBuilder.BuildIdLink(entityInstanceContext);
                if (idLink != null)
                {
                    entry.Id = idLink;
                }

                Uri readLink = linkBuilder.BuildReadLink(entityInstanceContext);
                if (readLink != null)
                {
                    entry.ReadLink = readLink;
                }

                Uri editLink = linkBuilder.BuildEditLink(entityInstanceContext);
                if (editLink != null)
                {
                    entry.EditLink = editLink;
                }
            }

            writer.WriteStart(entry);
            WriteNavigationLinks(entityInstanceContext, writer, writeContext);
            writer.WriteEnd();
        }
 internal static void SetEntitySetLinkBuilderAnnotation(this IEdmModel model, IEdmEntitySet entitySet, IEntitySetLinkBuilder entitySetLinkBuilder)
 {
     model.SetAnnotationValue(entitySet, entitySetLinkBuilder);
 }
Пример #14
0
        private void WriteFeed(object graph, ODataWriter writer, ODataSerializerContext writeContext)
        {
            IEnumerable enumerable = graph as IEnumerable; // Data to serialize

            if (enumerable != null)
            {
                ODataFeed feed = new ODataFeed();

                if (writeContext.EntitySet != null)
                {
                    IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);
                    FeedContext           feedContext = new FeedContext
                    {
                        EntitySet    = writeContext.EntitySet,
                        UrlHelper    = writeContext.UrlHelper,
                        PathHandler  = writeContext.PathHandler,
                        FeedInstance = graph
                    };

                    Uri feedSelfLink = linkBuilder.BuildFeedSelfLink(feedContext);
                    if (feedSelfLink != null)
                    {
                        feed.SetAnnotation(new AtomFeedMetadata()
                        {
                            SelfLink = new AtomLinkMetadata()
                            {
                                Relation = SelfLinkRelation, Href = feedSelfLink
                            }
                        });
                    }
                }

                // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ?
                feed.Id = FeedNamespace + _edmCollectionType.FullName();

                // If we have more OData format specific information apply it now.
                ODataResult odataFeedAnnotations = graph as ODataResult;
                if (odataFeedAnnotations != null)
                {
                    feed.Count        = odataFeedAnnotations.Count;
                    feed.NextPageLink = odataFeedAnnotations.NextPageLink;
                }
                else
                {
                    object             nextPageLinkPropertyValue;
                    HttpRequestMessage request = writeContext.Request;
                    if (request != null && request.Properties.TryGetValue(ODataQueryOptions.NextPageLinkPropertyKey, out nextPageLinkPropertyValue))
                    {
                        Uri nextPageLink = nextPageLinkPropertyValue as Uri;
                        if (nextPageLink != null)
                        {
                            feed.NextPageLink = nextPageLink;
                        }
                    }
                }

                writer.WriteStart(feed);

                foreach (object entry in enumerable)
                {
                    if (entry == null)
                    {
                        throw Error.NotSupported(SRResources.NullElementInCollection);
                    }

                    ODataSerializer entrySerializer = SerializerProvider.GetODataPayloadSerializer(entry.GetType());
                    if (entrySerializer == null)
                    {
                        throw Error.NotSupported(SRResources.TypeCannotBeSerialized, entry.GetType(), typeof(ODataMediaTypeFormatter).Name);
                    }

                    Contract.Assert(entrySerializer.ODataPayloadKind == ODataPayloadKind.Entry);

                    entrySerializer.WriteObjectInline(entry, writer, writeContext);
                }

                writer.WriteEnd();
            }
        }
 internal static void SetEntitySetLinkBuilderAnnotation(this IEdmModel model, IEdmEntitySet entitySet, IEntitySetLinkBuilder entitySetLinkBuilder)
 {
     model.SetAnnotationValue(entitySet, entitySetLinkBuilder);
 }