Example #1
0
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            // OData
            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Player>("Players");
            builder.EntitySet<BattingDetail>("BattingDetails");
            builder.EntitySet<BowlingDetail>("BowlingDetails");
            builder.EntitySet<Country>("Countrys");
            builder.EntitySet<Match>("Matches").EntityType.HasKey(m => m.MatchNumber);
            config.AddODataQueryFilter();
            config.MapODataServiceRoute(
                routeName: "odata",
                routePrefix: "odata",
                model: builder.GetEdmModel());
        }
Example #2
0
 private static IEdmModel GetEdmModel()
 {
     ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
     builder.EntitySet<Person>("Persons");
     var edmModel = builder.GetEdmModel();
     return edmModel;
 }
        /// <summary>
        /// Figures out the key properties and marks them as Keys in the EDM model.
        /// </summary>
        /// <param name="entity">The entity type being configured.</param>
        /// <param name="model">The <see cref="ODataModelBuilder"/>.</param>
        public override void Apply(EntityTypeConfiguration entity, ODataConventionModelBuilder model)
        {
            if (entity == null)
            {
                throw Error.ArgumentNull("entity");
            }

            // Suppress the EntityKeyConvention if there is any key in EntityTypeConfiguration.
            if (entity.Keys.Any() || entity.EnumKeys.Any())
            {
                return;
            }

            // Suppress the EntityKeyConvention if base type has any key.
            if (entity.BaseType != null && entity.BaseType.Keys().Any())
            {
                return;
            }

            PropertyConfiguration key = GetKeyProperty(entity);
            if (key != null)
            {
                entity.HasKey(key.PropertyInfo);
            }
        }
Example #4
0
        public static void Register(System.Web.Http.HttpConfiguration config)
        {
            // Web-API-Konfiguration und -Dienste

            // Web-API-Routen
            config.MapHttpAttributeRoutes();

            //ODataModelBuilder builder = new ODataConventionModelBuilder();
            //builder.EntitySet<Contracts.IResident>("Residents");
            //config.AddODataQueryFilter(new System.Web.Http.Filters.ActionFilterAttribute() );
            //config.Routes.MapODataRoute("ODataRoute", "odata", GetEdmModel());

            //ODataModelBuilder builder = new ODataConventionModelBuilder();
            //builder.EntitySet<Models.ResidentViewModel>("Residents");
            //config.MapODataServiceRoute(
            //    routeName: "ODataRoute",
            //    routePrefix: "odata",
            //    model: builder.GetEdmModel());

            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Models.ResidentViewModel>("ResidentViewModels");
            config.AddODataQueryFilter();
            //config.MapODataServiceRoute(routeName: "oDataRoute", routePrefix: "odata", model: builder.GetEdmModel());
            config.MapODataServiceRoute(routeName: "oDataRoute", routePrefix: "odata", model: builder.GetEdmModel());

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //config.MapODataServiceRoute( "odata", null, GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));

            config.EnsureInitialized();
        }
Example #5
0
        public static void Register(HttpConfiguration httpConfiguration)
        {
            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.Namespace = "ODataV4TestService.Models";
            builder.EntitySet<Product>("Products");
            builder.EntitySet<SuppliedProduct>("SuppliedProducts");
            builder.EntitySet<Supplier>("Suppliers");
            builder.EntitySet<Product>("OtherProducts");

            builder.ComplexType<Description>();
            builder.EntityType<Product>()
                .Action("Rate")
                .Parameter<int>("Rating");

            builder.EntityType<Product>().Collection
                .Function("Best")
                .ReturnsCollectionFromEntitySet<Product>("Products");

            var funcConfig = builder
                .EntityType<Product>()
                .Function("RelatedProducts")
                .SetBindingParameter("product", builder.GetTypeConfigurationOrNull(typeof(Product)))
                //.AddParameter("start", new PrimitiveTypeConfiguration(builder, builder.GetTypeConfigurationOrNull(typeof(DateTimeOffset)), typeof(DateTimeOffset)).
                .ReturnsCollectionFromEntitySet<Product>("Products");

            funcConfig
                .Parameter<DateTimeOffset>("start");

            funcConfig
                .Parameter<DateTimeOffset>("end");

            //builder.Function("GetSalesTaxRate")
            //    .Returns<double>()
            //    .Parameter<int>("PostalCode");

            builder.EntitySet<Account>("Accounts");

            builder.EntityType<PaymentInstrument>()
                .Collection
                .Function("GetCount")
                .Returns<int>()
                .Parameter<string>("NameContains");

            var model = builder.GetEdmModel();

            var conventions = ODataRoutingConventions.CreateDefault();
            conventions.Insert(0, new AttributeRoutingConvention(model, httpConfiguration));

            var server = new BatchServer(httpConfiguration);

            httpConfiguration.MapODataServiceRoute(
                routeName: "ODataRoute",
                routePrefix: null,
                model: model,
                pathHandler: new DefaultODataPathHandler(),
                routingConventions: conventions,
                batchHandler: new DefaultODataBatchHandler(server));

            httpConfiguration.MessageHandlers.Add(new TracingMessageHandler());
        }
        public void NavigationLinksGenerationConvention_GeneratesLinksWithCast_ForDerivedProperties()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Vehicle>("vehicles");
            builder.EntitySet<Manufacturer>("manufacturers");

            IEdmModel model = builder.GetEdmModel();
            IEdmEntitySet vehiclesEdmEntitySet = model.EntityContainer.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.MapODataServiceRoute(routeName, null, model);

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost");
            request.SetConfiguration(configuration);
            request.ODataProperties().RouteName = routeName;

            NavigationSourceLinkBuilderAnnotation linkBuilder = model.GetNavigationSourceLinkBuilder(vehiclesEdmEntitySet);

            var serializerContext = new ODataSerializerContext { Model = model, NavigationSource = 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.OData.Builder.TestModels.Car/Manufacturer", uri.AbsoluteUri);
        }
        private static IEdmModel GetModel()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            EntitySetConfiguration<Trade> tradesConfiguration = builder.EntitySet<Trade>("Trades");

            //Add bound function
            var boundFunction = tradesConfiguration.EntityType.Collection.Function("GetTradingVolume");
            boundFunction.Parameter<string>("productName");
            boundFunction.Parameter<Country>("portingCountry");
            boundFunction.Returns<long?>();

            //Add bound function
            boundFunction = tradesConfiguration.EntityType.Collection.Function("GetTopTrading");
            boundFunction.Parameter<string>("productName");
            boundFunction.ReturnsFromEntitySet<Trade>("Trades");
            boundFunction.IsComposable = true;

            //Add unbound function
            var unboundFunction = builder.Function("GetTradeByCountry");
            unboundFunction.Parameter<Country>("portingCountry");
            unboundFunction.ReturnsCollectionFromEntitySet<Trade>("Trades");

            builder.Namespace = typeof(Country).Namespace;

           return builder.GetEdmModel();
        }
        private static IEdmModel GetEdmModel(HttpConfiguration config)
        {
            var modelBuilder = new ODataConventionModelBuilder(config);
            var moviesEntitySet = modelBuilder.EntitySet<Movie>("Movies");

            // Now add actions.

            // CheckOut
            // URI: ~/odata/Movies(1)/ODataActionsSample.Models.CheckOut
            ActionConfiguration checkOutAction = modelBuilder.EntityType<Movie>().Action("CheckOut");
            checkOutAction.ReturnsFromEntitySet<Movie>("Movies");

            // ReturnMovie
            // URI: ~/odata/Movies(1)/ODataActionsSample.Models.Return
            // Binds to a single entity; no parameters.
            ActionConfiguration returnAction = modelBuilder.EntityType<Movie>().Action("Return");
            returnAction.ReturnsFromEntitySet<Movie>("Movies");

            // CheckOutMany action
            // URI: ~/odata/Movies/ODataActionsSample.Models.CheckOutMany
            // Binds to a collection of entities.  This action accepts a collection of parameters.
            ActionConfiguration checkOutManyAction = modelBuilder.EntityType<Movie>().Collection.Action("CheckOutMany");
            checkOutManyAction.CollectionParameter<int>("MovieIDs");
            checkOutManyAction.ReturnsCollectionFromEntitySet<Movie>("Movies");

            // CreateMovie action
            // URI: ~/odata/CreateMovie
            // Unbound action. It is invoked from the service root.
            ActionConfiguration createMovieAction = modelBuilder.Action("CreateMovie");
            createMovieAction.Parameter<string>("Title");
            createMovieAction.ReturnsFromEntitySet<Movie>("Movies");

            modelBuilder.Namespace = typeof(Movie).Namespace;
            return modelBuilder.GetEdmModel();
        }
		public static IEdmModel GetModel()
		{
			ODataModelBuilder builder = new ODataConventionModelBuilder();
			builder.Namespace = "D";
			builder.ContainerName = "Default";

			EntitySetConfiguration<City> cities = builder.EntitySet<City>("City");
			EntitySetConfiguration<Stadium> stadiums = builder.EntitySet<Stadium>("Stadium");

			// Per Collection Stadium
			FunctionConfiguration getStadiumsWithFunction = stadiums.EntityType.Collection.Function("GetStadiumsWithFunction");
			getStadiumsWithFunction.ReturnsCollectionFromEntitySet<Stadium>("Stadium");

			//  Per Collection Stadium, returns single entity
			FunctionConfiguration getStadiumsTest = stadiums.EntityType.Collection.Function("GetStadiumTest");
			getStadiumsTest.Parameter<string>("test");
			getStadiumsTest.Parameter<string>("name");
			getStadiumsTest.ReturnsFromEntitySet<Stadium>("Stadium");

			// Per Entity (Single key property) City
			FunctionConfiguration getStadiumFromCityWithFunction = cities.EntityType.Function("GetStadiumsFromCityWithFunction");
			getStadiumFromCityWithFunction.ReturnsCollectionFromEntitySet<Stadium>("Stadium");

			// Per Entity composite key Stadium
			FunctionConfiguration getCityFromStadiumWithFunction = stadiums.EntityType.Function("GetCityFromStadiumWithFunction");
			getCityFromStadiumWithFunction.ReturnsFromEntitySet<City>("City");

			// Global Function
			builder.Function("GlobalFunction").ReturnsCollectionFromEntitySet<Stadium>("Stadium");

			
			
			return builder.GetEdmModel();
		}
Example #10
0
 // Builds the EDM model
 private static IEdmModel GetEdmModel()
 {
     var builder = new ODataConventionModelBuilder();
     builder.EntitySet<Customer>("Customers");
     builder.EntitySet<Order>("Orders");
     return builder.GetEdmModel();
 }
        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.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')/System.Web.Http.OData.Builder.TestModels.Car/Manufacturer", uri.AbsoluteUri);
        }
Example #12
0
 private static IEdmModel GetModel()
 {
     ODataModelBuilder builder = new ODataConventionModelBuilder();
     EntitySetConfiguration<OrderByCustomer> customers = builder.EntitySet<OrderByCustomer>("OrderByCustomers");
     EntitySetConfiguration<OrderByOrder> orders = builder.EntitySet<OrderByOrder>("OrderByOrders");
     return builder.GetEdmModel();
 }
        public void Apply_Doesnot_Override_UserConfiguration()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            var vehicles = builder.EntitySet<Vehicle>("vehicles");
            var car = builder.AddEntityType(typeof(Car));
            var paintAction = vehicles.EntityType.Action("Paint");
            paintAction.HasActionLink(ctxt => new Uri("http://localhost/ActionTestWorks"), followsConventions: false);
            ActionLinkGenerationConvention convention = new ActionLinkGenerationConvention();

            convention.Apply(paintAction, builder);

            IEdmModel model = builder.GetEdmModel();
            var vehiclesEdmSet = model.EntityContainer.FindEntitySet("vehicles");
            var carEdmType = model.FindDeclaredType("System.Web.OData.Builder.TestModels.Car") as IEdmEntityType;
            var paintEdmAction =
                model.GetAvailableProcedures(
                    model.FindDeclaredType("System.Web.OData.Builder.TestModels.Car") as IEdmEntityType).Single()
                as IEdmAction;
            Assert.NotNull(paintEdmAction);

            HttpConfiguration configuration = new HttpConfiguration();
            configuration.Routes.MapODataServiceRoute(model);

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

            ActionLinkBuilder actionLinkBuilder = model.GetActionLinkBuilder(paintEdmAction);

            var serializerContext = new ODataSerializerContext { Model = model, NavigationSource = vehiclesEdmSet, Url = request.GetUrlHelper() };
            var entityContext = new EntityInstanceContext(serializerContext, carEdmType.AsReference(), new Car { Model = 2009, Name = "Contoso" });

            Uri link = actionLinkBuilder.BuildActionLink(entityContext);
            Assert.Equal("http://localhost/ActionTestWorks", link.AbsoluteUri);
        }
        public void Apply_DoesnotRemoveProperty_TypeIsDataContractAndPropertyHasDataMember()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            Mock<PropertyInfo> property = new Mock<PropertyInfo>();
            property.Setup(p => p.Name).Returns("Property");
            property.Setup(p => p.PropertyType).Returns(typeof(int));
            property.Setup(p => p.GetCustomAttributes(It.IsAny<Type>(), It.IsAny<bool>())).Returns(new Attribute[] 
            { 
                new IgnoreDataMemberAttribute(), 
                new DataContractAttribute() 
            });
            property.Setup(p => p.GetCustomAttributes(It.IsAny<bool>())).Returns(new Attribute[] 
            { new IgnoreDataMemberAttribute(), 
                new DataContractAttribute() 
            });

            Mock<Type> type = new Mock<Type>();
            type.Setup(t => t.GetCustomAttributes(It.IsAny<Type>(), It.IsAny<bool>())).Returns(new[] { new DataContractAttribute() });
            
            Mock<StructuralTypeConfiguration> structuralType = new Mock<StructuralTypeConfiguration>(MockBehavior.Strict);
            structuralType.Setup(s => s.ClrType).Returns(type.Object);

            Mock<PropertyConfiguration> primitiveProperty = new Mock<PropertyConfiguration>(property.Object, structuralType.Object);

            // Act
            new IgnoreDataMemberAttributeEdmPropertyConvention().Apply(primitiveProperty.Object, structuralType.Object, builder);

            // Assert
            structuralType.Verify();
        }
        public ParameterAliasNodeTranslatorTest()
        {
            var builder = new ODataConventionModelBuilder();
            builder.EntitySet<ParameterAliasCustomer>("Customers");
            builder.EntitySet<ParameterAliasOrder>("Orders");

            builder.EntityType<ParameterAliasCustomer>().Function("CollectionFunctionCall")
                .ReturnsCollection<int>().Parameter<int>("p1");

            builder.EntityType<ParameterAliasCustomer>().Function("EntityCollectionFunctionCall")
                .ReturnsCollectionFromEntitySet<ParameterAliasCustomer>("Customers").Parameter<int>("p1");

            builder.EntityType<ParameterAliasCustomer>().Function("SingleEntityFunctionCall")
                .Returns<ParameterAliasCustomer>().Parameter<int>("p1");

            builder.EntityType<ParameterAliasCustomer>().Function("SingleEntityFunctionCallWithoutParameters")
                .Returns<ParameterAliasCustomer>();

            builder.EntityType<ParameterAliasCustomer>().Function("SingleValueFunctionCall")
                .Returns<int>().Parameter<int>("p1");

            _model = builder.GetEdmModel();
            _customersEntitySet = _model.FindDeclaredEntitySet("Customers");
            _customerEntityType = _customersEntitySet.EntityType();
            _parameterAliasMappedNode = new ConstantNode(123);
        }
Example #16
0
        public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服务
            // 将 Web API 配置为仅使用不记名令牌身份验证。
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //有关OData
            //使用ODataConventionModelBuilder创建EDM使用了一些惯例
            //如果要对创建EDM有更多的控制,使用ODataModelBuilder
            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Product>("Products");//创建EntityDataModel(EDM)
            builder.EntitySet<Supplier>("Suppliers");
            config.MapODataServiceRoute(
                routeName: "ODataRoute",
                routePrefix: "odata",
                model: builder.GetEdmModel());
        }
        private static IEdmModel GetModel()
        {
            const string UsersSet = "Users";
            const string FriendshipsSet = "Friendships";
            const string TweetsSet = "Tweets";

            var builder = new ODataConventionModelBuilder();
            var users = builder.EntitySet<User>(UsersSet);
            builder.EntitySet<Friendship>(FriendshipsSet);
            builder.EntitySet<Tweet>(TweetsSet);

            users.EntityType.Ignore(u => u.Password);
            users.EntityType.Ignore(u => u.Email);

            // nameof(...) == "Login"
            builder.Namespace = "TwitterApi";
            var login = users.EntityType.Collection.Action(nameof(UsersController.Login));
            login.Parameter<string>(nameof(User.Password));
            login.Parameter<string>(nameof(User.Email));
            login.Returns<AuthenticateResponse>();

            var me = users.EntityType.Collection.Function(nameof(UsersController.Me));
            me.ReturnsFromEntitySet<User>(UsersSet);

            return builder.GetEdmModel();
        }
Example #18
0
 private static IEdmModel GetSampleModel()
 {
     ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
     builder.EntitySet<Employee>("employees");
     builder.EntitySet<WorkItem>("workitems");
     return builder.GetEdmModel();
 }
Example #19
0
 private IEdmModel GetEdmModel()
 {
     ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
     builder.EntitySet<Customer>("FormatCustomers");
     builder.Singleton<Customer>("This"); // Singleton
     return builder.GetEdmModel();
 }
Example #20
0
 private static IEdmModel GetModel()
 {
     ODataModelBuilder builder = new ODataConventionModelBuilder();
     builder.ContainerName = "CustomersContext";
     builder.EntitySet<Customer>("Customers");
     return builder.GetEdmModel();
 }
        public void IgnoreOfT_Should_AddToListOfIgnoredTypes()
        {
            var builder = new ODataConventionModelBuilder();
            builder.Ignore<object>();

            Assert.True(builder.IsIgnoredType(typeof(object)));
        }
 protected static IEdmModel GetEdmModel1(HttpConfiguration configuration)
 {
     var mb = new ODataConventionModelBuilder(configuration);
     mb.EntitySet<LinkGeneration_Model_v1>("LinkGeneration_Model1");
     mb.EntitySet<LinkGeneration_Model_v2>("LinkGeneration_Model2");
     return mb.GetEdmModel();
 }
Example #23
0
 public static IEdmModel GetEdmModel()
 {
     var builder = new ODataConventionModelBuilder();
     builder.EntitySet<Product>("Products");
     builder.EntitySet<Part>("Parts");
     return builder.GetEdmModel();
 }
        public void LowerCamelCaser_ProcessReflectedAndDataMemberAttributePropertyNames()
        {
            // Arrange
            var builder = new ODataConventionModelBuilder().EnableLowerCamelCase(
                NameResolverOptions.ProcessReflectedPropertyNames | NameResolverOptions.ProcessDataMemberAttributePropertyNames);
            EntityTypeConfiguration<LowerCamelCaserEntity> entityTypeConfiguration = builder.EntitySet<LowerCamelCaserEntity>("Entities").EntityType;
            entityTypeConfiguration.Property(b => b.ID).Name = "iD";
            entityTypeConfiguration.Property(d => d.Name).Name = "Name";
            entityTypeConfiguration.EnumProperty(d => d.Color).Name = "Something";
            ComplexTypeConfiguration<LowerCamelCaserComplex> complexTypeConfiguration = builder.ComplexType<LowerCamelCaserComplex>();
            complexTypeConfiguration.CollectionProperty(c => c.Notes).Name = "MyNotes";

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmEntityType lowerCamelCaserEntity = 
                Assert.Single(model.SchemaElements.OfType<IEdmEntityType>().Where(e => e.Name == "LowerCamelCaserEntity"));
            IEdmComplexType lowerCamelCaserComplex = 
                Assert.Single(model.SchemaElements.OfType<IEdmComplexType>().Where(e => e.Name == "LowerCamelCaserComplex"));
            Assert.Equal(5, lowerCamelCaserEntity.Properties().Count());
            Assert.Single(lowerCamelCaserEntity.Properties().Where(p => p.Name == "iD"));
            Assert.Single(lowerCamelCaserEntity.Properties().Where(p => p.Name == "Name"));
            Assert.Single(lowerCamelCaserEntity.Properties().Where(p => p.Name == "details"));
            Assert.Single(lowerCamelCaserEntity.Properties().Where(p => p.Name == "Something"));
            Assert.Single(lowerCamelCaserEntity.Properties().Where(p => p.Name == "complexProperty"));
            Assert.Equal(2, lowerCamelCaserComplex.Properties().Count());
            Assert.Single(lowerCamelCaserComplex.Properties().Where(p => p.Name == "price"));
            Assert.Single(lowerCamelCaserComplex.Properties().Where(p => p.Name == "MyNotes"));
        }
    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureWebApi(IAppBuilder app)
    {
      var config = new HttpConfiguration();

      // Web API routes
      config.MapHttpAttributeRoutes(); //NB Must come before OData route mapping
      config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });

      // OData:  Create the OData model.  Here, we're using the convention model builder that will use OData
      // convention defaults for model creation and routing.
      ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
      
      // All entity properties should be in lower camel case
      builder.EnableLowerCamelCase();

      // Because PersonSearchHit inherits from SearchHit, we'll ignore it.
      // This gets around the convention builder's decision to create an entity out of the SearchHit object.
      builder.Ignore<PersonSearchHit>();

      // Create two entity sets:
      // One for search features and one that will retrieve a given person.
      builder.EntitySet<IndexSearch>("Search");
      builder.EntitySet<Person>("People");
      
      // OData model registration and route creation
      config.MapODataServiceRoute("ODataRoute", null, builder.GetEdmModel());

      // Set up the bearer token that will be required to do OData calls.
      WebApiConfigBearerToken.Configure(config);

      app.UseWebApi(config);
    }
 private static IEdmModel GetEdmModel()
 {
     var builder = new ODataConventionModelBuilder();
     builder.EntitySet<ResponseDataModel>("Users");
     builder.EntitySet<CustomerCardAdministrationDataModel>("CustomerCards");
     return builder.GetEdmModel();
 }
Example #27
0
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            //config.MapHttpAttributeRoutes();

            //config.Routes.MapHttpRoute(
            //    name: "DefaultApi",
            //    routeTemplate: "api/{controller}/{id}",
            //    defaults: new { id = RouteParameter.Optional }
            //);
 
            config.EnableCors();
            var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
            config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);

            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.Namespace = "Demos";
            builder.ContainerName = "DefaultContainer";
            builder.EntitySet<Person>("Peoples");
            config.MapODataServiceRoute(
               routeName: "ODataRoute",
               routePrefix: "odata",
               model: builder.GetEdmModel());
           // config.MapODataServiceRoute("odata", "odata", GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
            config.EnsureInitialized();
        }
        public void Validate_DepthChecks_DollarLevels(string expand, int maxExpansionDepth)
        {
            // Arrange
            var validator = new SelectExpandQueryValidator();
            var builder = new ODataConventionModelBuilder();
            builder.EntitySet<ODataLevelsTest.LevelsEntity>("Entities");
            IEdmModel model = builder.GetEdmModel();
            var context = new ODataQueryContext(model, typeof(ODataLevelsTest.LevelsEntity));
            var selectExpandQueryOption = new SelectExpandQueryOption(null, expand, context);
            selectExpandQueryOption.LevelsMaxLiteralExpansionDepth = 1;

            // Act & Assert
            Assert.Throws<ODataException>(
                () => validator.Validate(
                    selectExpandQueryOption,
                    new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth }),
                String.Format(
                    CultureInfo.CurrentCulture,
                    "The request includes a $expand path which is too deep. The maximum depth allowed is {0}. " +
                    "To increase the limit, set the 'MaxExpansionDepth' property on EnableQueryAttribute or ODataValidationSettings.",
                    maxExpansionDepth));

            Assert.DoesNotThrow(
                () => validator.Validate(
                    selectExpandQueryOption,
                    new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth + 1 }));
        }
 private static IEdmModel GetInheritanceModel(HttpConfiguration config)
 {
     ODataModelBuilder builder = new ODataConventionModelBuilder(config);
     var baseEntitySet = builder.EntitySet<BaseEntity>("BaseEntity");
     var derivedEntityType = builder.EntityType<DerivedEntity>().DerivesFrom<BaseEntity>();
     return builder.GetEdmModel();
 }
        public override IEdmModel GetModel(Type elementClrType, HttpRequestMessage request,
            HttpActionDescriptor actionDescriptor)
        {
            // Get model for the request
            IEdmModel model = request.ODataProperties().Model;

            if (model == null)
            {
                // user has not configured anything or has registered a model without the element type
                // let's create one just for this type and cache it in the action descriptor
                model = actionDescriptor.Properties.GetOrAdd("System.Web.OData.Model+" + elementClrType.FullName, _ =>
                {
                    ODataConventionModelBuilder builder =
                        new ODataConventionModelBuilder(actionDescriptor.Configuration, isQueryCompositionMode: true);
                    builder.EnableLowerCamelCase();
                    EntityTypeConfiguration entityTypeConfiguration = builder.AddEntityType(elementClrType);
                    builder.AddEntitySet(elementClrType.Name, entityTypeConfiguration);
                    IEdmModel edmModel = builder.GetEdmModel();
                    Contract.Assert(edmModel != null);
                    return edmModel;
                }) as IEdmModel;
            }

            Contract.Assert(model != null);
            return model;
        }
Example #31
0
 partial void OnConfigureOData(ODataConventionModelBuilder builder);
Example #32
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            IServiceProvider provider = app.ApplicationServices.GetRequiredService <IServiceProvider>();

            app.UseCors(builder =>
                        builder.WithOrigins("*")
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials()
                        .AllowAnyOrigin()
                        );

            app.Use(async(context, next) => {
                if (context.Request.Path.Value == "/__ssrsreport" || context.Request.Path.Value == "/ssrsproxy")
                {
                    await next();
                    return;
                }
                try
                {
                    await next();
                }
#pragma warning disable 0168
                catch (Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException ex) {
#pragma warning restore 0168
                    if (!Path.HasExtension(context.Request.Path.Value))
                    {
                        context.Request.Path = "/index.html";
                        await next();
                    }
                }

                if ((context.Response.StatusCode == 404 || context.Response.StatusCode == 401) && !Path.HasExtension(context.Request.Path.Value))
                {
                    context.Request.Path = "/index.html";
                    await next();
                }
            });

            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseDeveloperExceptionPage();

            app.UseMvc(builder =>
            {
                builder.Count().Filter().OrderBy().Expand().Select().MaxTop(null).SetTimeZoneInfo(TimeZoneInfo.Utc);

                if (env.EnvironmentName == "Development")
                {
                    builder.MapRoute(name: "default",
                                     template: "{controller}/{action}/{id?}",
                                     defaults: new { controller = "Home", action = "Index" }
                                     );
                }

                var oDataBuilder = new ODataConventionModelBuilder(provider);

                oDataBuilder.EntitySet <CustomSecurity.Models.CustomSecurity.Role>("Roles");
                oDataBuilder.EntitySet <CustomSecurity.Models.CustomSecurity.User>("Users");

                var userRole = oDataBuilder.EntitySet <CustomSecurity.Models.CustomSecurity.UserRole>("UserRoles");
                userRole.EntityType.HasKey(entity => new {
                    entity.UserId, entity.RoleId
                });

                this.OnConfigureOData(oDataBuilder);

                oDataBuilder.EntitySet <ApplicationUser>("ApplicationUsers");
                var usersType = oDataBuilder.StructuralTypes.First(x => x.ClrType == typeof(ApplicationUser));
                usersType.AddCollectionProperty(typeof(ApplicationUser).GetProperty("RoleNames"));
                oDataBuilder.EntitySet <IdentityRole>("ApplicationRoles");

                var model = oDataBuilder.GetEdmModel();

                builder.MapODataServiceRoute("odata/CustomSecurity", "odata/CustomSecurity", model);

                builder.MapODataServiceRoute("auth", "auth", model);
            });

            if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("RADZEN")) && env.IsDevelopment())
            {
                app.UseSpa(spa =>
                {
                    spa.Options.SourcePath = "../client";
                    spa.UseAngularCliServer(npmScript: "start -- --port 8000 --open");
                });
            }

            OnConfigure(app);
        }
Example #33
0
        private static IEdmModel GetFunctionsEdmModel()
        {
            var builder = new ODataConventionModelBuilder();

            builder.EnableLowerCamelCase();

            builder.EntitySet <Product>("Products");

            var productType = builder.EntityType <Product>();

            // Function bound to a collection that accepts an enum parameter
            var enumParamFunction = productType.Collection.Function("GetByEnumValue");

            enumParamFunction.Parameter <MyEnum>("EnumValue");
            enumParamFunction.ReturnsCollectionFromEntitySet <Product>("Products");

            var enumParamEntityFunction = productType.Function("IsEnumValueMatch");

            enumParamEntityFunction.Parameter <MyEnum>("EnumValue");
            enumParamEntityFunction.Returns <bool>();

            // Function bound to an entity set
            // Returns the most expensive product, a single entity
            productType.Collection
            .Function("MostExpensive")
            .Returns <double>();

            // Function bound to an entity set
            // Returns the top 10 product, a collection
            productType.Collection
            .Function("Top10")
            .ReturnsCollectionFromEntitySet <Product>("Products");

            // Function bound to a single entity
            // Returns the instance's price rank among all products
            productType
            .Function("GetPriceRank")
            .Returns <int>();

            // Function bound to a single entity
            // Accept a string as parameter and return a double
            // This function calculate the general sales tax base on the
            // state
            productType
            .Function("CalculateGeneralSalesTax")
            .Returns <double>()
            .Parameter <string>("state");

            // Function bound to an entity set
            // Accepts an array as a parameter
            productType.Collection
            .Function("ProductsWithIds")
            .ReturnsCollectionFromEntitySet <Product>("Products")
            .CollectionParameter <int>("Ids");

            // An action bound to an entity set
            // Accepts multiple action parameters
            var createAction = productType.Collection.Action("Create");

            createAction.ReturnsFromEntitySet <Product>("Products");
            createAction.Parameter <string>("Name").OptionalParameter      = false;
            createAction.Parameter <double>("Price").OptionalParameter     = false;
            createAction.Parameter <MyEnum>("EnumValue").OptionalParameter = false;

            // An action bound to an entity set
            // Accepts an array of complex types
            var postArrayAction = productType.Collection.Action("PostArray");

            postArrayAction.ReturnsFromEntitySet <Product>("Products");
            postArrayAction.CollectionParameter <ProductDto>("products").OptionalParameter = false;

            // An action bound to an entity
            productType.Action("Rate")
            .Parameter <int>("Rating");

            return(builder.GetEdmModel());
        }
 /// <summary>
 /// Applies the convention.
 /// </summary>
 /// <param name="edmTypeConfiguration">The edm type to apply the convention to.</param>
 /// <param name="model">The model that this edm type belongs to.</param>
 /// <param name="attribute">The attribute found on this edm type.</param>
 public abstract void Apply(TEdmTypeConfiguration edmTypeConfiguration, ODataConventionModelBuilder model,
                            Attribute attribute);
Example #35
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            IServiceProvider provider = app.ApplicationServices.GetRequiredService <IServiceProvider>();

            app.UseCors(builder =>
                        builder.WithOrigins("*")
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials()
                        .AllowAnyOrigin()
                        );

            app.Use(async(context, next) => {
                try
                {
                    await next();
                }
#pragma warning disable 0168
                catch (Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException ex) {
#pragma warning restore 0168
                    if (!Path.HasExtension(context.Request.Path.Value))
                    {
                        context.Request.Path = "/index.html";
                        await next();
                    }
                }

                if ((context.Response.StatusCode == 404 || context.Response.StatusCode == 401) && !Path.HasExtension(context.Request.Path.Value))
                {
                    context.Request.Path = "/index.html";
                    await next();
                }
            });

            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseDeveloperExceptionPage();

            app.UseMvc(builder =>
            {
                builder.Count().Filter().OrderBy().Expand().Select().MaxTop(null).SetTimeZoneInfo(TimeZoneInfo.Utc);

                if (env.EnvironmentName == "Development")
                {
                    builder.MapRoute(name: "default",
                                     template: "{controller}/{action}/{id?}",
                                     defaults: new { controller = "Home", action = "Index" }
                                     );
                }

                var oDataBuilder = new ODataConventionModelBuilder(provider);

                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.Category>("Categories");
                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.Customer>("Customers");

                var customerCustomerDemo = oDataBuilder.EntitySet <TreeGrid.Models.Northwind.CustomerCustomerDemo>("CustomerCustomerDemos");
                customerCustomerDemo.EntityType.HasKey(entity => new {
                    entity.CustomerID, entity.CustomerTypeID
                });
                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.CustomerDemographic>("CustomerDemographics");
                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.Employee>("Employees");

                var employeeTerritory = oDataBuilder.EntitySet <TreeGrid.Models.Northwind.EmployeeTerritory>("EmployeeTerritories");
                employeeTerritory.EntityType.HasKey(entity => new {
                    entity.EmployeeID, entity.TerritoryID
                });
                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.Order>("Orders");

                var orderDetail = oDataBuilder.EntitySet <TreeGrid.Models.Northwind.OrderDetail>("OrderDetails");
                orderDetail.EntityType.HasKey(entity => new {
                    entity.OrderID, entity.ProductID
                });
                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.Product>("Products");
                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.Region>("Regions");
                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.Shipper>("Shippers");
                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.Supplier>("Suppliers");
                oDataBuilder.EntitySet <TreeGrid.Models.Northwind.Territory>("Territories");

                this.OnConfigureOData(oDataBuilder);

                var model = oDataBuilder.GetEdmModel();

                builder.MapODataServiceRoute("odata/Northwind", "odata/Northwind", model);
            });


            if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("RADZEN")) && env.IsDevelopment())
            {
                app.UseSpa(spa =>
                {
                    spa.Options.SourcePath = "../client";
                    spa.UseAngularCliServer(npmScript: "start -- --port 8000 --open");
                });
            }

            OnConfigure(app);
        }
        public void ReadResource_CanReadDynamicPropertiesForOpenEntityType()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntityType <SimpleOpenCustomer>();
            builder.EnumType <SimpleEnum>();
            IEdmModel model = builder.GetEdmModel();

            IEdmEntityTypeReference customerTypeReference = model.GetEdmTypeReference(typeof(SimpleOpenCustomer)).AsEntity();

            var deserializer = new ODataResourceDeserializer(_deserializerProvider);

            ODataEnumValue enumValue = new ODataEnumValue("Third", typeof(SimpleEnum).FullName);

            ODataResource[] complexResources =
            {
                new ODataResource
                {
                    TypeName   = typeof(SimpleOpenAddress).FullName,
                    Properties = new[]
                    {
                        // declared properties
                        new ODataProperty {
                            Name = "Street", Value = "Street 1"
                        },
                        new ODataProperty {
                            Name = "City", Value = "City 1"
                        },

                        // dynamic properties
                        new ODataProperty
                        {
                            Name  = "DateTimeProperty",
                            Value = new DateTimeOffset(new DateTime(2014, 5, 6))
                        }
                    }
                },
                new ODataResource
                {
                    TypeName   = typeof(SimpleOpenAddress).FullName,
                    Properties = new[]
                    {
                        // declared properties
                        new ODataProperty {
                            Name = "Street", Value = "Street 2"
                        },
                        new ODataProperty {
                            Name = "City", Value = "City 2"
                        },

                        // dynamic properties
                        new ODataProperty
                        {
                            Name  = "ArrayProperty",
                            Value = new ODataCollectionValue{
                                TypeName = "Collection(Edm.Int32)", Items = new[]{                                         1, 2, 3, 4 }.Cast <object>()
                            }
                        }
                    }
                }
            };

            ODataResource odataResource = new ODataResource
            {
                Properties = new[]
                {
                    // declared properties
                    new ODataProperty {
                        Name = "CustomerId", Value = 991
                    },
                    new ODataProperty {
                        Name = "Name", Value = "Name #991"
                    },

                    // dynamic properties
                    new ODataProperty {
                        Name = "GuidProperty", Value = new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA")
                    },
                    new ODataProperty {
                        Name = "EnumValue", Value = enumValue
                    },
                },
                TypeName = typeof(SimpleOpenCustomer).FullName
            };

            ODataDeserializerContext readContext = new ODataDeserializerContext()
            {
                Model = model
            };

            ODataResourceWrapper topLevelResourceWrapper = new ODataResourceWrapper(odataResource);

            ODataNestedResourceInfo resourceInfo = new ODataNestedResourceInfo
            {
                IsCollection = true,
                Name         = "CollectionProperty"
            };
            ODataNestedResourceInfoWrapper resourceInfoWrapper = new ODataNestedResourceInfoWrapper(resourceInfo);
            ODataResourceSetWrapper        resourceSetWrapper  = new ODataResourceSetWrapper(new ODataResourceSet
            {
                TypeName = String.Format("Collection({0})", typeof(SimpleOpenAddress).FullName)
            });

            foreach (var complexResource in complexResources)
            {
                resourceSetWrapper.Resources.Add(new ODataResourceWrapper(complexResource));
            }
            resourceInfoWrapper.NestedItems.Add(resourceSetWrapper);
            topLevelResourceWrapper.NestedResourceInfos.Add(resourceInfoWrapper);

            // Act
            SimpleOpenCustomer customer = deserializer.ReadResource(topLevelResourceWrapper, customerTypeReference, readContext)
                                          as SimpleOpenCustomer;

            // Assert
            Assert.NotNull(customer);

            // Verify the declared properties
            Assert.Equal(991, customer.CustomerId);
            Assert.Equal("Name #991", customer.Name);

            // Verify the dynamic properties
            Assert.NotNull(customer.CustomerProperties);
            Assert.Equal(3, customer.CustomerProperties.Count());
            Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), customer.CustomerProperties["GuidProperty"]);
            Assert.Equal(SimpleEnum.Third, customer.CustomerProperties["EnumValue"]);

            // Verify the dynamic collection property
            var collectionValues = Assert.IsType <List <SimpleOpenAddress> >(customer.CustomerProperties["CollectionProperty"]);

            Assert.NotNull(collectionValues);
            Assert.Equal(2, collectionValues.Count());

            Assert.Equal(new DateTimeOffset(new DateTime(2014, 5, 6)), collectionValues[0].Properties["DateTimeProperty"]);
            Assert.Equal(new List <int> {
                1, 2, 3, 4
            }, collectionValues[1].Properties["ArrayProperty"]);
        }
Example #37
0
        /// <inheritdoc/>
        public async Task <IEdmModel> GetModelAsync(ModelContext context, CancellationToken cancellationToken)
        {
            // This means user build a model with customized model builder registered as inner most
            // Its element will be added to built model.
            IEdmModel innerModel = null;

            if (InnerModelBuilder != null)
            {
                innerModel = await InnerModelBuilder.GetModelAsync(context, cancellationToken);
            }

            var entitySetTypeMap = context.EntitySetTypeMap;

            if (entitySetTypeMap == null || entitySetTypeMap.Count == 0)
            {
                return(innerModel);
            }

            // Collection of entity type and set name is set by EF now,
            // and EF model producer will not build model any more
            // Web Api OData conversion model built is been used here,
            // refer to Web Api OData document for the detail conversions been used for model built.
            var builder = new ODataConventionModelBuilder();

            // This namespace is used by container
            builder.Namespace = entitySetTypeMap.First().Value.Namespace;

            MethodInfo method = typeof(ODataConventionModelBuilder)
                                .GetMethod("EntitySet", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);

            foreach (var pair in entitySetTypeMap)
            {
                // Build a method with the specific type argument
                var specifiedMethod = method.MakeGenericMethod(pair.Value);
                var parameters      = new object[]
                {
                    pair.Key
                };

                specifiedMethod.Invoke(builder, parameters);
            }

            entitySetTypeMap.Clear();

            var entityTypeKeyPropertiesMap = context.EntityTypeKeyPropertiesMap;

            if (entityTypeKeyPropertiesMap != null)
            {
                foreach (var pair in entityTypeKeyPropertiesMap)
                {
                    var edmTypeConfiguration = builder.GetTypeConfigurationOrNull(pair.Key) as EntityTypeConfiguration;
                    if (edmTypeConfiguration == null)
                    {
                        continue;
                    }

                    foreach (var property in pair.Value)
                    {
                        edmTypeConfiguration.HasKey(property);
                    }
                }

                entityTypeKeyPropertiesMap.Clear();
            }

            var model = (EdmModel)builder.GetEdmModel();

            // Add all Inner model content into existing model
            // When WebApi OData make conversion model builder accept an existing model, this can be removed.
            if (innerModel != null)
            {
                foreach (var element in innerModel.SchemaElements)
                {
                    if (!(element is EdmEntityContainer))
                    {
                        model.AddElement(element);
                    }
                }

                foreach (var annotation in innerModel.VocabularyAnnotations)
                {
                    model.AddVocabularyAnnotation(annotation);
                }

                var entityContainer      = (EdmEntityContainer)model.EntityContainer;
                var innerEntityContainer = (EdmEntityContainer)innerModel.EntityContainer;
                if (innerEntityContainer != null)
                {
                    foreach (var entityset in innerEntityContainer.EntitySets())
                    {
                        if (entityContainer.FindEntitySet(entityset.Name) == null)
                        {
                            entityContainer.AddEntitySet(entityset.Name, entityset.EntityType());
                        }
                    }

                    foreach (var singleton in innerEntityContainer.Singletons())
                    {
                        if (entityContainer.FindEntitySet(singleton.Name) == null)
                        {
                            entityContainer.AddSingleton(singleton.Name, singleton.EntityType());
                        }
                    }

                    foreach (var operation in innerEntityContainer.OperationImports())
                    {
                        if (entityContainer.FindOperationImports(operation.Name) == null)
                        {
                            if (operation.IsFunctionImport())
                            {
                                entityContainer.AddFunctionImport(
                                    operation.Name, (EdmFunction)operation.Operation, operation.EntitySet);
                            }
                            else
                            {
                                entityContainer.AddActionImport(
                                    operation.Name, (EdmAction)operation.Operation, operation.EntitySet);
                            }
                        }
                    }
                }
            }

            return(model);
        }
        private static IEdmModel GetEdmModel()
        {
            var builder = new ODataConventionModelBuilder();

            builder.Namespace     = "AirVinyl";
            builder.ContainerName = "AirVinylContainer";

            builder.EntitySet <Person>("People");
            builder.EntitySet <RecordStore>("RecordStores");

            // function bound to RecordStore entity
            var isHighRatedFunction = builder.EntityType <RecordStore>()
                                      .Function("IsHighRated");

            isHighRatedFunction.Returns <bool>();
            isHighRatedFunction.Parameter <int>("minimumRating");
            isHighRatedFunction.Namespace = "AirVinyl.Functions";

            // function bound to RecordStore list
            var areRatedByFunction = builder.EntityType <RecordStore>().Collection
                                     .Function("AreRatedBy");

            areRatedByFunction.ReturnsCollectionFromEntitySet <RecordStore>("RecordStores");
            areRatedByFunction.CollectionParameter <int>("personIds");
            areRatedByFunction.Namespace = "AirVinyl.Functions";

            // unbound function(no entity type)
            var getHighRatedRecordStoresFunction = builder.Function("GetHighRatedRecordStores");

            getHighRatedRecordStoresFunction.Parameter <int>("minimumRating");
            getHighRatedRecordStoresFunction.ReturnsCollectionFromEntitySet <RecordStore>("RecordStores");
            getHighRatedRecordStoresFunction.Namespace = "AirVinyl.Functions";

            // action bound to RecordStore entity
            var rateAction = builder.EntityType <RecordStore>()
                             .Action("Rate");

            rateAction.Returns <bool>();
            rateAction.Parameter <int>("rating");
            rateAction.Parameter <int>("personId");
            rateAction.Namespace = "AirVinyl.Actions";

            // action bound to RecordStore collection
            var removeRatingsAction = builder.EntityType <RecordStore>().Collection
                                      .Action("RemoveRatings");

            removeRatingsAction.Returns <bool>();
            removeRatingsAction.Parameter <int>("personId");
            removeRatingsAction.Namespace = "AirVinyl.Actions";

            // unbound action
            var removeRecordStoreRatingsAction = builder.Action("RemoveRecordStoreRatings");

            removeRecordStoreRatingsAction.Parameter <int>("personId");
            removeRecordStoreRatingsAction.Namespace = "AirVinyl.Actions";

            // "Tim" singleton
            builder.Singleton <Person>("Tim");

            return(builder.GetEdmModel());
        }
Example #39
0
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
                );

            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            var currency = builder.EntitySet <DimCurrency>("Currencies");

            currency.EntityType.Ignore(p => p.FactCurrencyRates);

            var dates = builder.EntitySet <DimDate>("Dates");

            dates.EntityType.Ignore(p => p.FactCallCenters);
            dates.EntityType.Ignore(p => p.FactCurrencyRates);
            dates.EntityType.Ignore(p => p.FactFinances);
            dates.EntityType.Ignore(p => p.FactSalesQuotas);
            dates.EntityType.Ignore(p => p.FactSurveyResponses);

            var employee = builder.EntitySet <DimEmployee>("Employees");

            employee.EntityType.Ignore(p => p.FactSalesQuotas);

            builder.EntitySet <FactInternetSale>("InternetSales");

            var org = builder.EntitySet <DimOrganization>("Organizations");

            org.EntityType.Ignore(p => p.FactFinances);

            builder.EntitySet <DimProductCategory>("ProductCategories");
            builder.EntitySet <FactProductInventory>("ProductInventories");
            builder.EntitySet <DimProduct>("Products");
            builder.EntitySet <DimProductSubcategory>("ProductSubcategories");
            builder.EntitySet <DimPromotion>("Promotions");
            builder.EntitySet <FactResellerSale>("ResellerSales");
            builder.EntitySet <DimSalesTerritory>("SalesTerritories");

            var customer = builder.EntitySet <DimCustomer>("Customers");

            customer.EntityType.Ignore(p => p.FactSurveyResponses);

            builder.EntitySet <DimGeography>("Geographies");
            builder.EntitySet <DimReseller>("Resellers");
            builder.EntitySet <DimSalesReason>("SalesReasons");

            var function = builder.Function("SpecialReportSales");

            function.Parameter <int>("MaxAmount");
            function.ReturnsCollectionFromEntitySet <FactInternetSale>("InternetSales");

            config.AddODataQueryFilter();
            config.MapODataServiceRoute(
                "odata",
                "odata",
                builder.GetEdmModel());

            config.SetDefaultQuerySettings(new System.Web.OData.Query.DefaultQuerySettings
            {
                EnableCount   = true,
                EnableExpand  = true,
                EnableFilter  = true,
                EnableOrderBy = true,
                EnableSelect  = true,
                MaxTop        = null
            });

            config.EnableDependencyInjection();
            config.EnsureInitialized();
        }
 /// <summary>
 /// Applies the convention.
 /// </summary>
 /// <param name="edmProperty">The property being configured.</param>
 /// <param name="structuralTypeConfiguration">The type being configured.</param>
 /// <param name="attribute">The attribute to be used during configuration.</param>
 /// <param name="model">The ODataConventionModelBuilder used to build the model.</param>
 public abstract void Apply(TPropertyConfiguration edmProperty,
                            StructuralTypeConfiguration structuralTypeConfiguration,
                            Attribute attribute,
                            ODataConventionModelBuilder model);
Example #41
0
        private static IEdmModel GetModel()
        {
            HttpConfiguration config = new HttpConfiguration();

            config.Services.Replace(typeof(IAssembliesResolver), new TestAssemblyResolver(typeof(Customer)));
            ODataModelBuilder builder = new ODataConventionModelBuilder(config);

            builder.ContainerName = "C";
            builder.Namespace     = "A.B";
            EntityTypeConfiguration <Customer> customer = builder.EntitySet <Customer>("Customers").EntityType;

            // bound actions
            ActionConfiguration primitive = customer.Action("Primitive");

            primitive.Parameter <int>("Quantity");
            primitive.Parameter <string>("ProductCode");
            primitive.Parameter <Date>("Birthday");
            primitive.Parameter <AColor>("BkgColor");
            primitive.Parameter <AColor?>("InnerColor");

            ActionConfiguration complex = customer.Action("Complex");

            complex.Parameter <int>("Quantity");
            complex.Parameter <MyAddress>("Address");

            ActionConfiguration enumType = customer.Action("Enum");

            enumType.Parameter <AColor>("Color");

            ActionConfiguration primitiveCollection = customer.Action("PrimitiveCollection");

            primitiveCollection.Parameter <string>("Name");
            primitiveCollection.CollectionParameter <int>("Ratings");
            primitiveCollection.CollectionParameter <TimeOfDay>("Time");
            primitiveCollection.CollectionParameter <AColor?>("Colors");

            ActionConfiguration complexCollection = customer.Action("ComplexCollection");

            complexCollection.Parameter <string>("Name");
            complexCollection.CollectionParameter <MyAddress>("Addresses");

            ActionConfiguration enumCollection = customer.Action("EnumCollection");

            enumCollection.CollectionParameter <AColor>("Colors");

            ActionConfiguration entity = customer.Action("Entity");

            entity.Parameter <int>("Id");
            entity.EntityParameter <Customer>("Customer");
            entity.EntityParameter <Customer>("NullableCustomer");

            ActionConfiguration entityCollection = customer.Action("EntityCollection");

            entityCollection.Parameter <int>("Id");
            entityCollection.CollectionEntityParameter <Customer>("Customers");

            // unbound actions
            ActionConfiguration unboundPrimitive = builder.Action("UnboundPrimitive");

            unboundPrimitive.Parameter <int>("Quantity");
            unboundPrimitive.Parameter <string>("ProductCode");
            unboundPrimitive.Parameter <Date>("Birthday");
            unboundPrimitive.Parameter <AColor>("BkgColor");
            unboundPrimitive.Parameter <AColor?>("InnerColor");

            ActionConfiguration unboundComplex = builder.Action("UnboundComplex");

            unboundComplex.Parameter <int>("Quantity");
            unboundComplex.Parameter <MyAddress>("Address");

            ActionConfiguration unboundEnum = builder.Action("UnboundEnum");

            unboundEnum.Parameter <AColor>("Color");

            ActionConfiguration unboundPrimitiveCollection = builder.Action("UnboundPrimitiveCollection");

            unboundPrimitiveCollection.Parameter <string>("Name");
            unboundPrimitiveCollection.CollectionParameter <int>("Ratings");
            unboundPrimitiveCollection.CollectionParameter <TimeOfDay>("Time");
            unboundPrimitiveCollection.CollectionParameter <AColor?>("Colors");

            ActionConfiguration unboundComplexCollection = builder.Action("UnboundComplexCollection");

            unboundComplexCollection.Parameter <string>("Name");
            unboundComplexCollection.CollectionParameter <MyAddress>("Addresses");

            ActionConfiguration unboundEnumCollection = builder.Action("UnboundEnumCollection");

            unboundEnumCollection.CollectionParameter <AColor>("Colors");

            ActionConfiguration unboundEntity = builder.Action("UnboundEntity");

            unboundEntity.Parameter <int>("Id");
            unboundEntity.EntityParameter <Customer>("Customer").OptionalParameter = false;
            unboundEntity.EntityParameter <Customer>("NullableCustomer");

            ActionConfiguration unboundEntityCollection = builder.Action("UnboundEntityCollection");

            unboundEntityCollection.Parameter <int>("Id");
            unboundEntityCollection.CollectionEntityParameter <Customer>("Customers");

            return(builder.GetEdmModel());
        }
Example #42
0
 private static void ConfigureModelToSupportOdata(ODataConventionModelBuilder builder)
 {
 }
Example #43
0
        public static IEdmModel GetEdmModel(IApplicationBuilder app)
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            builder.EnableLowerCamelCase();
            builder.EntitySet <LeadDetail>("LeadDetail");
            builder.EntitySet <CashRegister>("CashRegister");
            builder.EntitySet <LanguageKey>("LanguageKey").EntityType.HasKey(x => new { x.LanguageCode, x.Key });
            builder.EntitySet <CashRegisterOpening>("CashRegisterOpening");
            builder.EntitySet <CashRegisterOpeningDetail>("CashRegisterOpeningDetail").HasOptionalBinding(x => x.CashRegisterOpening, "CashRegisterOpening");
            builder.EntitySet <CustomerPayment>("CustomerPayment");
            builder.EntitySet <ProductSupplierCost>("ProductCost");
            builder.EntitySet <CompositeProduct>("CompositeProduct");
            builder.EntitySet <UnitProductEquivalence>("ProductUnit");
            builder.EntitySet <CreditNote>("CreditNote");
            builder.EntitySet <Currency>("Currency");
            builder.EntitySet <Customer>("Customer");
            builder.EntitySet <School>("School");
            builder.EntitySet <CustomerBalance>("CustomerBalance");
            builder.EntitySet <CustomerReturn>("CustomerReturn");
            builder.EntitySet <CustomerReturnDetail>("CustomerReturnDetail");
            builder.EntitySet <Expense>("Expense");
            builder.EntitySet <ExpenseTax>("ExpenseTax");
            builder.EntitySet <ExpensesPayment>("ExpensesPayment");
            builder.EntitySet <InventoryEntry>("InventoryEntry").HasOptionalBinding(x => x.BranchOffice, "BranchOffice");
            builder.EntitySet <InventoryEntry>("InventoryEntry").HasOptionalBinding(x => x.Warehouse, "Warehouse");
            builder.EntitySet <InventoryEntry>("InventoryEntry").HasOptionalBinding(x => x.Supplier, "Supplier");
            builder.EntitySet <InventoryEntry>("InventoryEntry").HasOptionalBinding(x => x.Product, "Product");
            builder.EntitySet <InventoryEntry>("InventoryEntry").HasOptionalBinding(x => x.Unit, "Unit");
            builder.EntitySet <InventoryEntry>("InventoryEntry").HasOptionalBinding(x => x.Currency, "Currency");
            builder.EntitySet <Invoice>("Invoice");
            builder.EntitySet <InvoiceLead>("InvoiceLead");
            builder.EntitySet <InvoiceTax>("InvoiceTax");
            builder.EntitySet <BranchOffice>("BranchOffice").HasManyBinding(x => x.Warehouses, "Warehouse");
            builder.EntitySet <MovementType>("MovementType");
            builder.EntitySet <OpeningAmount>("OpeningAmount");
            builder.EntitySet <PaymentType>("PaymentType");
            builder.EntitySet <PaymentDetail>("PaymentDetail");
            builder.EntitySet <Product>("Product").HasOptionalBinding(x => x.Currency, "Currency");
            builder.EntitySet <ProductTax>("ProductTax");
            builder.EntitySet <ReturnDetail>("ReturnDetail");
            builder.EntitySet <Seller>("Seller");
            builder.EntitySet <SequenceControl>("SequenceControl");
            builder.EntitySet <SupplierReturn>("SupplierReturn");
            builder.EntitySet <Supplier>("Supplier");
            builder.EntitySet <Language>("Language");
            builder.EntitySet <SupplierBalance>("SupplierBalance");
            builder.EntitySet <Tax>("Tax");
            builder.EntitySet <TRNControl>("TRNControl");
            builder.EntitySet <Unit>("Unit");
            builder.EntitySet <UnitProductEquivalence>("UnitProductEquivalence");
            builder.EntitySet <Warehouse>("Warehouse").EntityType.HasKey(x => x.Id);
            builder.EntitySet <Warehouse>("Warehouse").HasOptionalBinding(x => x.BranchOffice, "BranchOffice");
            builder.EntitySet <WarehouseMovement>("WarehouseMovement");
            builder.EntitySet <Inventory>("Inventory");
            builder.EntitySet <WarehouseTransfer>("WarehouseTransfer");
            builder.EntitySet <WarehouseTransfer>("WarehouseTransfer").HasOptionalBinding(x => x.Destiny, "Destiny");
            builder.EntitySet <WarehouseTransfer>("WarehouseTransfer").HasOptionalBinding(x => x.DestinyBranchOffice, "DestinyBranchOffice");
            builder.EntitySet <WarehouseTransfer>("WarehouseTransfer").HasOptionalBinding(x => x.Origin, "Origin");
            builder.EntitySet <WarehouseTransfer>("WarehouseTransfer").HasOptionalBinding(x => x.OriginBranchOffice, "OriginBranchOffice");
            builder.EntitySet <WarehouseTransfer>("WarehouseTransfer").HasOptionalBinding(x => x.Product, "Product");
            builder.EntitySet <WarehouseTransfer>("WarehouseTransfer").HasOptionalBinding(x => x.Unit, "Unit");
            builder.EntitySet <Zone>("Zone");
            builder.EntitySet <Section>("Section");
            builder.EntitySet <SectionOperation>("SectionOperation");
            builder.EntitySet <Operation>("Operation");
            builder.EntitySet <Role>("Role");
            builder.EntitySet <RoleSectionOperation>("RoleSectionOperation").HasOptionalBinding(x => x.Operation, "Operation");
            builder.EntitySet <RoleSectionOperation>("RoleSectionOperation").HasOptionalBinding(x => x.Section, "Section");
            builder.EntitySet <User>("User");
            builder.EntitySet <UserClaims>("UserClaims");
            builder.EntitySet <UserRole>("UserRole");
            builder.EntitySet <CompanyPayments>("CompanyPayment");
            builder.EntitySet <CompanyPayments>("CompanyPayment").HasOptionalBinding(x => x.PaymentType, "PaymentType");
            builder.EntitySet <CompanyPayments>("CompanyPayment").HasOptionalBinding(x => x.Currency, "Currency");

            builder.EntitySet <SupplierReturn>("SupplierReturn");
            builder.EntitySet <SupplierReturn>("SupplierReturn").HasOptionalBinding(x => x.Currency, "Currency");
            builder.EntitySet <SupplierReturn>("SupplierReturn").HasOptionalBinding(x => x.BranchOffice, "BranchOffice");
            builder.EntitySet <SupplierReturn>("SupplierReturn").HasOptionalBinding(x => x.Warehouse, "Warehouse");
            builder.EntitySet <SupplierReturn>("SupplierReturn").HasOptionalBinding(x => x.Supplier, "Supplier");
            builder.EntitySet <SupplierReturn>("SupplierReturn").HasOptionalBinding(x => x.Product, "Product");
            builder.EntitySet <SupplierReturn>("SupplierReturn").HasOptionalBinding(x => x.Unit, "Unit");

            return(builder.GetEdmModel());
        }
        // Builds the EDM model for the OData service, including the OData action definitions.
        private static IEdmModel GetEdmModel()
        {
            var modelBuilder = new ODataConventionModelBuilder();

            modelBuilder.EntitySet <Vedio>("Vedios");

            ActionConfiguration returnAcAction = modelBuilder.Action("ReturnAc");

            returnAcAction.Parameter <int>("key");
            returnAcAction.ReturnsFromEntitySet <Vedio>("Vedios");

            FunctionConfiguration checkOutAction = modelBuilder.Function("CheckOut");

            checkOutAction.Parameter <int>("key");
            checkOutAction.ReturnsFromEntitySet <Vedio>("Vedios");

            ActionConfiguration createMovieAction = modelBuilder.Action("CreateVedio");

            createMovieAction.Parameter <Vedio>("vedio");
            createMovieAction.ReturnsFromEntitySet <Vedio>("Vedios");

            ActionConfiguration ListAcAction = modelBuilder.Action("ListAc");

            ListAcAction.Parameter <Window>("windows");
            ListAcAction.Returns <int>();

            ActionConfiguration checkOutManyAction = modelBuilder.Action("CheckOutMany");

            checkOutManyAction.CollectionParameter <int>("MovieIDs");
            checkOutManyAction.ReturnsCollectionFromEntitySet <Vedio>("Vedios");

            //######################################################################################################//
            modelBuilder.EntitySet <QueryResult>("QueryResults");

            FunctionConfiguration GetRunningTasks = modelBuilder.Function("GetRunningTasks");

            GetRunningTasks.Parameter <QueryEntity>("query");
            GetRunningTasks.ReturnsCollectionFromEntitySet <QueryResult>("QueryResults");

            FunctionConfiguration GetReadyTasks = modelBuilder.Function("GetReadyTasks");

            GetReadyTasks.Parameter <QueryEntity>("query");
            GetReadyTasks.ReturnsCollectionFromEntitySet <QueryResult>("QueryResults");

            //######################################################################################################//

            ActionConfiguration StartProcess = modelBuilder.Action("StartProcess");

            StartProcess.Parameter <WfRunner>("WfRunner");
            StartProcess.Returns <int>();

            ActionConfiguration RunProcess = modelBuilder.Action("RunProcess");

            RunProcess.Parameter <WfRunner>("WfRunner");
            RunProcess.Returns <string>();

            ActionConfiguration WithdrawProcess = modelBuilder.Action("WithdrawProcess");

            WithdrawProcess.Parameter <WfRunner>("WfRunner");
            WithdrawProcess.Returns <string>();

            ActionConfiguration SendBackProcess = modelBuilder.Action("SendBackProcess");

            SendBackProcess.Parameter <WfRunner>("WfRunner");
            SendBackProcess.Returns <string>();

            ActionConfiguration JumpProcess = modelBuilder.Action("JumpProcess");

            JumpProcess.Parameter <WfRunner>("WfRunner");
            JumpProcess.Returns <string>();

            ActionConfiguration ReverseProcess = modelBuilder.Action("ReverseProcess");

            ReverseProcess.Parameter <WfRunner>("WfRunner");
            ReverseProcess.Returns <string>();

            ActionConfiguration DiscardProcess = modelBuilder.Action("DiscardProcess");

            DiscardProcess.Parameter <WfRunner>("WfRunner");
            DiscardProcess.Returns <string>();

            modelBuilder.Namespace = "WF";
            return(modelBuilder.GetEdmModel());
        }
        public async Task SendAsync_CorrectlyHandlesCookieHeader()
        {
            var batchRef     = $"batch_{Guid.NewGuid()}";
            var changesetRef = $"changeset_{Guid.NewGuid()}";
            var endpoint     = "http://localhost";

            Type[] controllers = new[] { typeof(BatchTestCustomersController), typeof(BatchTestOrdersController) };

            var builder = new WebHostBuilder()
                          .ConfigureServices(services =>
            {
                var builder = new ODataConventionModelBuilder();
                builder.EntitySet <BatchTestOrder>("BatchTestOrders");
                IEdmModel model = builder.GetEdmModel();
                services.AddControllers().AddOData(opt => opt.AddModel(model, new DefaultODataBatchHandler()).Expand());
            })
                          .Configure(app =>
            {
                ApplicationPartManager applicationPartManager = app.ApplicationServices.GetRequiredService <ApplicationPartManager>();
                applicationPartManager.ApplicationParts.Clear();

                if (controllers != null)
                {
                    AssemblyPart part = new AssemblyPart(new MockAssembly(controllers));
                    applicationPartManager.ApplicationParts.Add(part);
                }

                app.UseODataBatching();
                app.UseRouting();
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            });

            var server = new TestServer(builder);
            var client = server.CreateClient();

            var orderId            = 2;
            var createOrderPayload = $@"{{""@odata.type"":""Microsoft.AspNetCore.OData.Test.Batch.BatchTestOrder"",""Id"":{orderId},""Amount"":50}}";

            var batchRequest = new HttpRequestMessage(HttpMethod.Post, $"{endpoint}/$batch");

            batchRequest.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("text/plain"));

            // Add cookie (for example IdentityServer adds antiforgery after login)
            batchRequest.Headers.TryAddWithoutValidation("Cookie", ".AspNetCore.Antiforgery.9TtSrW0hzOs=" + Guid.NewGuid());

            var batchContent = $@"
--{batchRef}
Content-Type: multipart/mixed;boundary={changesetRef}

--{changesetRef}
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

POST {endpoint}/BatchTestOrders HTTP/1.1
Content-Type: application/json;type=entry
Prefer: return=representation

{createOrderPayload}
--{changesetRef}--
--{batchRef}
Content-Type: application/http
Content-Transfer-Encoding: binary

GET {endpoint}/BatchTestOrders({orderId}) HTTP/1.1
Content-Type: application/json;type=entry
Prefer: return=representation

--{batchRef}--
";

            var httpContent = new StringContent(batchContent);

            httpContent.Headers.ContentType   = MediaTypeHeaderValue.Parse($"multipart/mixed;boundary={batchRef}");
            httpContent.Headers.ContentLength = batchContent.Length;
            batchRequest.Content = httpContent;
            var response = await client.SendAsync(batchRequest);

            ExceptionAssert.DoesNotThrow(() => response.EnsureSuccessStatusCode());

            // TODO: assert somehow?
        }
 public override void Apply(TConventionType edmTypeConfiguration, ODataConventionModelBuilder model,
                            Attribute attribute)
 {
     ModelBuilder = model;
     Attribute    = attribute;
 }
        public async Task SendAsync_Works_ForBatchRequestWithInsertedEntityReferencedInAnotherRequest()
        {
            // Arrange
            var builder = new WebHostBuilder()
                          .ConfigureServices(services =>
            {
                services.ConfigureControllers(typeof(BatchTestCustomersController), typeof(BatchTestOrdersController));
                var builder = new ODataConventionModelBuilder();
                builder.EntitySet <BatchTestCustomer>("BatchTestCustomers");
                builder.EntitySet <BatchTestOrder>("BatchTestOrders");
                IEdmModel model = builder.GetEdmModel();
                services.AddControllers().AddOData(opt => opt.AddModel("odata", model, new DefaultODataBatchHandler()).Expand());
            })
                          .Configure(app =>
            {
                app.UseODataBatching();
                app.UseRouting();
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            });

            var server = new TestServer(builder);

            const string acceptJsonFullMetadata = "application/json;odata.metadata=minimal";
            const string acceptJson             = "application/json";

            var client = server.CreateClient();

            var endpoint = "http://localhost/odata";

            var batchRef     = $"batch_{Guid.NewGuid()}";
            var changesetRef = $"changeset_{Guid.NewGuid()}";

            var orderId            = 2;
            var createOrderPayload = $@"{{""@odata.type"":""Microsoft.AspNetCore.OData.Test.Batch.BatchTestOrder"",""Id"":{orderId},""Amount"":50}}";
            var createRefPayload   = @"{""@odata.id"":""$3""}";

            var batchRequest = new HttpRequestMessage(HttpMethod.Post, $"{endpoint}/$batch");

            batchRequest.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("multipart/mixed"));
            StringContent httpContent = new StringContent($@"
--{batchRef}
Content-Type: multipart/mixed; boundary={changesetRef}

--{changesetRef}
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 3

POST {endpoint}/BatchTestOrders HTTP/1.1
OData-Version: 4.0;NetFx
OData-MaxVersion: 4.0;NetFx
Content-Type: {acceptJsonFullMetadata}
Accept: {acceptJsonFullMetadata}
Accept-Charset: UTF-8

{createOrderPayload}
--{changesetRef}
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 4

POST {endpoint}/BatchTestCustomers(2)/Orders/$ref HTTP/1.1
OData-Version: 4.0;NetFx
OData-MaxVersion: 4.0;NetFx
Content-Type: {acceptJsonFullMetadata}
Accept: {acceptJsonFullMetadata}
Accept-Charset: UTF-8

{createRefPayload}
--{changesetRef}--
--{batchRef}--
");

            httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"multipart/mixed; boundary={batchRef}");
            batchRequest.Content            = httpContent;

            // Act
            var response = await client.SendAsync(batchRequest);

            // Assert
            ExceptionAssert.DoesNotThrow(() => response.EnsureSuccessStatusCode());

            HttpRequestMessage customerRequest = new HttpRequestMessage(HttpMethod.Get, $"{endpoint}/BatchTestCustomers(2)?$expand=Orders");

            customerRequest.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse(acceptJson));

            var customerResponse = client.SendAsync(customerRequest).Result;
            var objAsJsonString  = await customerResponse.Content.ReadAsStringAsync();

            var customer = JsonConvert.DeserializeObject <BatchTestCustomer>(objAsJsonString);

            Assert.NotNull(customer.Orders?.SingleOrDefault(d => d.Id.Equals(orderId)));
        }
Example #48
0
        public static IEdmModel GetModel()
        {
            var configuration = RoutingConfigurationFactory.CreateWithTypes();
            ODataConventionModelBuilder builder = ODataConventionModelBuilderFactory.Create(configuration);

            builder.EntitySet <RoutingCustomer>("RoutingCustomers");
            builder.EntitySet <Product>("Products");
            builder.EntitySet <SalesPerson>("SalesPeople");
            builder.EntitySet <EmailAddress>("EmailAddresses");
            builder.EntitySet <üCategory>("üCategories");
            builder.EntitySet <EnumCustomer>("EnumCustomers");
            builder.Singleton <RoutingCustomer>("VipCustomer");
            builder.Singleton <Product>("MyProduct");
            builder.EntitySet <DateTimeOffsetKeyCustomer>("DateTimeOffsetKeyCustomers");
            builder.EntitySet <Destination>("Destinations");
            builder.EntitySet <Incident>("Incidents");
            builder.ComplexType <Dog>();
            builder.ComplexType <Cat>();
            builder.EntityType <SpecialProduct>();
            builder.ComplexType <UsAddress>();

            ActionConfiguration getRoutingCustomerById = builder.Action("GetRoutingCustomerById");

            getRoutingCustomerById.Parameter <int>("RoutingCustomerId");
            getRoutingCustomerById.ReturnsFromEntitySet <RoutingCustomer>("RoutingCustomers");

            ActionConfiguration getSalesPersonById = builder.Action("GetSalesPersonById");

            getSalesPersonById.Parameter <int>("salesPersonId");
            getSalesPersonById.ReturnsFromEntitySet <SalesPerson>("SalesPeople");

            ActionConfiguration getAllVIPs = builder.Action("GetAllVIPs");

            ActionReturnsCollectionFromEntitySet <VIP>(builder, getAllVIPs, "RoutingCustomers");

            builder.EntityType <RoutingCustomer>().ComplexProperty <Address>(c => c.Address);
            builder.EntityType <RoutingCustomer>().Action("GetRelatedRoutingCustomers").ReturnsCollectionFromEntitySet <RoutingCustomer>("RoutingCustomers");

            ActionConfiguration getBestRelatedRoutingCustomer = builder.EntityType <RoutingCustomer>().Action("GetBestRelatedRoutingCustomer");

            ActionReturnsFromEntitySet <VIP>(builder, getBestRelatedRoutingCustomer, "RoutingCustomers");

            ActionConfiguration getVIPS = builder.EntityType <RoutingCustomer>().Collection.Action("GetVIPs");

            ActionReturnsCollectionFromEntitySet <VIP>(builder, getVIPS, "RoutingCustomers");

            builder.EntityType <RoutingCustomer>().Collection.Action("GetProducts").ReturnsCollectionFromEntitySet <Product>("Products");
            builder.EntityType <VIP>().Action("GetSalesPerson").ReturnsFromEntitySet <SalesPerson>("SalesPeople");
            builder.EntityType <VIP>().Collection.Action("GetSalesPeople").ReturnsCollectionFromEntitySet <SalesPerson>("SalesPeople");

            ActionConfiguration getMostProfitable = builder.EntityType <VIP>().Collection.Action("GetMostProfitable");

            ActionReturnsFromEntitySet <VIP>(builder, getMostProfitable, "RoutingCustomers");

            ActionConfiguration getVIPRoutingCustomers = builder.EntityType <SalesPerson>().Action("GetVIPRoutingCustomers");

            ActionReturnsCollectionFromEntitySet <VIP>(builder, getVIPRoutingCustomers, "RoutingCustomers");

            ActionConfiguration getVIPRoutingCustomersOnCollection = builder.EntityType <SalesPerson>().Collection.Action("GetVIPRoutingCustomers");

            ActionReturnsCollectionFromEntitySet <VIP>(builder, getVIPRoutingCustomersOnCollection, "RoutingCustomers");

            builder.EntityType <VIP>().HasRequired(v => v.RelationshipManager);
            builder.EntityType <ImportantProduct>().HasRequired(ip => ip.LeadSalesPerson);

            // function bound to an entity
            FunctionConfiguration topProductId = builder.EntityType <Product>().Function("TopProductId");

            topProductId.Returns <int>();

            FunctionConfiguration topProductIdByCity = builder.EntityType <Product>().Function("TopProductIdByCity");

            topProductIdByCity.Parameter <string>("city");
            topProductIdByCity.Returns <string>();

            FunctionConfiguration topProductIdByCityAndModel = builder.EntityType <Product>().Function("TopProductIdByCityAndModel");

            topProductIdByCityAndModel.Parameter <string>("city");
            topProductIdByCityAndModel.Parameter <int>("model");
            topProductIdByCityAndModel.Returns <string>();

            FunctionConfiguration optionFunctions = builder.EntityType <Product>().Collection.Function("GetCount").Returns <int>();

            optionFunctions.Parameter <double>("minSalary");
            optionFunctions.Parameter <double>("maxSalary").Optional();
            optionFunctions.Parameter <double>("aveSalary").Optional().HasDefaultValue("1200.99");

            // function bound to a collection of entities
            FunctionConfiguration topProductOfAll = builder.EntityType <Product>().Collection.Function("TopProductOfAll");

            topProductOfAll.Returns <string>();

            FunctionConfiguration topProductOfAllByCity = builder.EntityType <Product>().Collection.Function("TopProductOfAllByCity");

            topProductOfAllByCity.Parameter <string>("city");
            topProductOfAllByCity.Returns <string>();

            FunctionConfiguration copyProductByCity = builder.EntityType <Product>().Function("CopyProductByCity");

            copyProductByCity.Parameter <string>("city");
            copyProductByCity.Returns <string>();

            FunctionConfiguration topProductOfAllByCityAndModel = builder.EntityType <Product>().Collection.Function("TopProductOfAllByCityAndModel");

            topProductOfAllByCityAndModel.Parameter <string>("city");
            topProductOfAllByCityAndModel.Parameter <int>("model");
            topProductOfAllByCityAndModel.Returns <string>();

            // Function bound to the base entity type and derived entity type
            builder.EntityType <RoutingCustomer>().Function("GetOrdersCount").Returns <string>();
            builder.EntityType <VIP>().Function("GetOrdersCount").Returns <string>();

            // Overloaded function only bound to the base entity type with one paramter
            var getOrderCount = builder.EntityType <RoutingCustomer>().Function("GetOrdersCount");

            getOrderCount.Parameter <int>("factor");
            getOrderCount.Returns <string>();

            // Function only bound to the derived entity type
            builder.EntityType <SpecialVIP>().Function("GetSpecialGuid").Returns <string>();

            // Function bound to the collection of the base and the derived entity type
            builder.EntityType <RoutingCustomer>().Collection.Function("GetAllEmployees").Returns <string>();
            builder.EntityType <VIP>().Collection.Function("GetAllEmployees").Returns <string>();

            // Bound function with enum type parameters
            var boundFunction = builder.EntityType <RoutingCustomer>().Collection.Function("BoundFuncWithEnumParameters");

            boundFunction.Parameter <SimpleEnum>("SimpleEnum");
            boundFunction.Parameter <FlagsEnum>("FlagsEnum");
            boundFunction.Returns <string>();

            // Bound function with enum type parameter for attribute routing
            var boundFunctionForAttributeRouting = builder.EntityType <RoutingCustomer>().Collection
                                                   .Function("BoundFuncWithEnumParameterForAttributeRouting");

            boundFunctionForAttributeRouting.Parameter <SimpleEnum>("SimpleEnum");
            boundFunctionForAttributeRouting.Returns <string>();

            // Unbound function with enum type parameters
            var function = builder.Function("UnboundFuncWithEnumParameters");

            function.Parameter <LongEnum>("LongEnum");
            function.Parameter <FlagsEnum>("FlagsEnum");
            function.Returns <string>();

            // Unbound function
            builder.Function("UnboundFunction").ReturnsCollection <int>().IsComposable = true;

            // Action only bound to the derived entity type
            builder.EntityType <SpecialVIP>().Action("ActionBoundToSpecialVIP");

            // Action only bound to the derived entity type
            builder.EntityType <SpecialVIP>().Collection.Action("ActionBoundToSpecialVIPs");

            // Function only bound to the base entity collection type
            builder.EntityType <RoutingCustomer>().Collection.Function("FunctionBoundToRoutingCustomers").Returns <int>();

            // Function only bound to the derived entity collection type
            builder.EntityType <VIP>().Collection.Function("FunctionBoundToVIPs").Returns <int>();

            // Bound function with multiple parameters
            var functionBoundToProductWithMultipleParamters = builder.EntityType <Product>().Function("FunctionBoundToProductWithMultipleParamters");

            functionBoundToProductWithMultipleParamters.Parameter <int>("P1");
            functionBoundToProductWithMultipleParamters.Parameter <int>("P2");
            functionBoundToProductWithMultipleParamters.Parameter <string>("P3");
            functionBoundToProductWithMultipleParamters.Returns <int>();

            // Overloaded bound function with no parameter
            builder.EntityType <Product>().Function("FunctionBoundToProduct").Returns <int>();

            // Overloaded bound function with one parameter
            builder.EntityType <Product>().Function("FunctionBoundToProduct").Returns <int>().Parameter <int>("P1");

            // Overloaded bound function with multiple parameters
            var functionBoundToProduct = builder.EntityType <Product>().Function("FunctionBoundToProduct").Returns <int>();

            functionBoundToProduct.Parameter <int>("P1");
            functionBoundToProduct.Parameter <int>("P2");
            functionBoundToProduct.Parameter <string>("P3");

            // Unbound function with one parameter
            var unboundFunctionWithOneParamters = builder.Function("UnboundFunctionWithOneParamters");

            unboundFunctionWithOneParamters.Parameter <int>("P1");
            unboundFunctionWithOneParamters.ReturnsFromEntitySet <RoutingCustomer>("RoutingCustomers");
            unboundFunctionWithOneParamters.IsComposable = true;

            // Unbound function with multiple parameters
            var functionWithMultipleParamters = builder.Function("UnboundFunctionWithMultipleParamters");

            functionWithMultipleParamters.Parameter <int>("P1");
            functionWithMultipleParamters.Parameter <int>("P2");
            functionWithMultipleParamters.Parameter <string>("P3");
            functionWithMultipleParamters.Returns <int>();

            // Overloaded unbound function with no parameter
            builder.Function("OverloadUnboundFunction").Returns <int>();

            // Overloaded unbound function with one parameter
            builder.Function("OverloadUnboundFunction").Returns <int>().Parameter <int>("P1");

            // Overloaded unbound function with multiple parameters
            var overloadUnboundFunction = builder.Function("OverloadUnboundFunction").Returns <int>();

            overloadUnboundFunction.Parameter <int>("P1");
            overloadUnboundFunction.Parameter <int>("P2");
            overloadUnboundFunction.Parameter <string>("P3");

            var functionWithComplexTypeParameter =
                builder.EntityType <RoutingCustomer>().Function("CanMoveToAddress").Returns <bool>();

            functionWithComplexTypeParameter.Parameter <Address>("address");

            var functionWithCollectionOfComplexTypeParameter =
                builder.EntityType <RoutingCustomer>().Function("MoveToAddresses").Returns <bool>();

            functionWithCollectionOfComplexTypeParameter.CollectionParameter <Address>("addresses");

            var functionWithCollectionOfPrimitiveTypeParameter =
                builder.EntityType <RoutingCustomer>().Function("CollectionOfPrimitiveTypeFunction").Returns <bool>();

            functionWithCollectionOfPrimitiveTypeParameter.CollectionParameter <int>("intValues");

            var functionWithEntityTypeParameter =
                builder.EntityType <RoutingCustomer>().Function("EntityTypeFunction").Returns <bool>();

            functionWithEntityTypeParameter.EntityParameter <Product>("product");

            var functionWithCollectionEntityTypeParameter =
                builder.EntityType <RoutingCustomer>().Function("CollectionEntityTypeFunction").Returns <bool>();

            functionWithCollectionEntityTypeParameter.CollectionEntityParameter <Product>("products");

            return(builder.GetEdmModel());
        }
 public AbpWebApiODataModuleConfiguration()
 {
     ODataModelBuilder = new ODataConventionModelBuilder();
 }
        public async Task SendAsync_CorrectlyCopiesHeadersToIndividualRequests(
            IEnumerable <string> batchPreferHeaderValues,
            string getRequest,
            string deleteRequest,
            string postRequest)
        {
            var batchRef               = $"batch_{Guid.NewGuid()}";
            var changesetRef           = $"changeset_{Guid.NewGuid()}";
            var endpoint               = "http://localhost/odata";
            var acceptJsonFullMetadata = "application/json;odata.metadata=minimal";
            var postPayload            = "Bar";

            Type[] controllers = new[] { typeof(BatchTestHeadersCustomersController) };
            var    builder     = new WebHostBuilder()
                                 .ConfigureServices(services =>
            {
                var builder = new ODataConventionModelBuilder();
                builder.EntitySet <BatchTestHeadersCustomer>("BatchTestHeadersCustomers");
                IEdmModel model = builder.GetEdmModel();
                services.AddControllers().AddOData(opt => opt.AddModel("odata", model, new DefaultODataBatchHandler()).Expand());
            })
                                 .Configure(app =>
            {
                ApplicationPartManager applicationPartManager = app.ApplicationServices.GetRequiredService <ApplicationPartManager>();
                applicationPartManager.ApplicationParts.Clear();

                if (controllers != null)
                {
                    AssemblyPart part = new AssemblyPart(new MockAssembly(controllers));
                    applicationPartManager.ApplicationParts.Add(part);
                }

                app.UseODataBatching();
                app.UseRouting();
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            });

            var server = new TestServer(builder);
            var client = server.CreateClient();

            var batchRequest = new HttpRequestMessage(HttpMethod.Post, $"{endpoint}/$batch");

            batchRequest.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("multipart/mixed"));
            batchRequest.Headers.Add("Prefer", batchPreferHeaderValues);

            var batchContent = $@"
--{batchRef}
Content-Type: application/http
Content-Transfer-Encoding: binary

GET {endpoint}/BatchTestHeadersCustomers HTTP/1.1
OData-Version: 4.0
OData-MaxVersion: 4.0
Accept: application/json;odata.metadata=minimal
Accept-Charset: UTF-8


--{batchRef}
Content-Type: application/http
Content-Transfer-Encoding: binary

DELETE {endpoint}/BatchTestHeadersCustomers(1) HTTP/1.1
OData-Version: 4.0
OData-MaxVersion: 4.0
Accept: application/json;odata.metadata=minimal
Accept-Charset: UTF-8
Prefer: wait=100,handling=lenient


--{batchRef}
Content-Type: application/http
Content-Transfer-Encoding: binary

POST {endpoint}/BatchTestHeadersCustomers HTTP/1.1
OData-Version: 4.0;NetFx
OData-MaxVersion: 4.0;NetFx
Content-Type: text/plain; charset=utf-8
Content-Length: {postPayload.Length}
Accept: {acceptJsonFullMetadata}
Accept-Charset: UTF-8

{postPayload}
--{batchRef}--
";

            var httpContent = new StringContent(batchContent);

            httpContent.Headers.ContentType   = MediaTypeHeaderValue.Parse($"multipart/mixed; boundary={batchRef}");
            httpContent.Headers.ContentLength = batchContent.Length;
            batchRequest.Content = httpContent;
            var response = await client.SendAsync(batchRequest);

            ExceptionAssert.DoesNotThrow(() => response.EnsureSuccessStatusCode());
            var responseContent = await response.Content.ReadAsStringAsync();

            Assert.Contains(getRequest, responseContent);
            Assert.Contains(deleteRequest, responseContent);
            Assert.Contains(postRequest, responseContent);
        }
Example #51
0
        public static ODataRoute MapOdataActionApi <T>(this HttpConfiguration config, string routePrefix) where T : ODataController
        {
            // Use the Controller Namespace and name as the Odata container and schema
            var builder = new ODataConventionModelBuilder();

            builder.Namespace     = typeof(T).Namespace;
            builder.ContainerName = typeof(T).Name.Substring(0, typeof(T).Name.LastIndexOf("Controller"));

            // Add any Entity Types from the controller attributes.  The rest will be ComplexTypes
            foreach (var att in typeof(T).GetCustomAttributes <EntitySetAttribute>())
            {
                builder.AddEntitySet(att.EntitySetName, builder.AddEntity(att.EntityType));
            }

            // Discover the Odata actions from controller methods with attributes
            var actions = from m in typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public)
                          where Attribute.IsDefined(m, typeof(ODataActionAttribute))
                          select new
            {
                Name            = m.Name,
                Description     = (m.GetCustomAttribute <DescriptionAttribute>() ?? DescriptionAttribute.Default).Description,
                ReturnType      = m.GetCustomAttribute <ODataActionAttribute>().ReturnType,
                IsSideEffecting = m.GetCustomAttribute <ODataActionAttribute>().IsSideEffecting,
                Parameters      = from p in m.GetParameters()
                                  select new
                {
                    Name         = p.Name,
                    Description  = (p.GetCustomAttribute <DescriptionAttribute>() ?? DescriptionAttribute.Default).Description,
                    IsOptional   = p.IsOptional,
                    ReturnType   = p.ParameterType,
                    SampleValues = GetSampleValue(p),
                    EnumValues   = GetEnumValues(p)
                }
            };


            // Create Odata Function Imports for all the actions
            foreach (var action in actions)
            {
                // create a Function Import for the action
                var actionConfig = builder.Action(action.Name);

                // set the return type
                if (action.ReturnType != null)
                {
                    actionConfig.ReturnType = GetOrAddComplexType(builder, action.ReturnType);

                    // If the Action returns an Entity or collection of entities then we need to associate the action to the EntitySet or serialization will fail
                    var collectionType = actionConfig.ReturnType as CollectionTypeConfiguration;
                    var entityType     = collectionType != null ? collectionType.ElementType : actionConfig.ReturnType;
                    actionConfig.EntitySet = builder.EntitySets.FirstOrDefault(e => e.EntityType == entityType);
                }

                // add the parameters
                foreach (var parameter in action.Parameters)
                {
                    actionConfig.AddParameter(parameter.Name, GetOrAddComplexType(builder, parameter.ReturnType));
                }
            }


            // Build the Edm Model for the API
            var model = builder.GetEdmModel();

            // Now edit the Edm Model to add Marketplace documentation annotations
            foreach (var functionImport in model.EntityContainers().SelectMany(c => c.FunctionImports()))
            {
                // get the action for the import
                var action = actions.FirstOrDefault(a => a.Name == functionImport.Name);
                if (action != null)
                {
                    // The marketplace doesnt seem to be reading this on the function right now, but lets add it anyway
                    model.AddMarketplaceAnnotation(functionImport, "Description", action.Description);

                    // add the parameter annotations
                    foreach (var parameter in functionImport.Parameters)
                    {
                        // Set the action parameter annotations
                        var actionParam = action.Parameters.First(p => p.Name == parameter.Name);
                        model.AddMarketplaceAnnotation(parameter, "SampleValues", actionParam.SampleValues);
                        model.AddMarketplaceAnnotation(parameter, "Enum", string.Join("|", actionParam.EnumValues));
                        model.AddMarketplaceAnnotation(parameter, "Description", actionParam.Description);

                        // The marketplace is using the IsNullable property to determine if a field is optional.  Unfortunatly this is not public so just use reflection to set it
                        typeof(EdmTypeReference).InvokeMember("isNullable", BindingFlags.SetField | BindingFlags.Instance | BindingFlags.NonPublic, null, parameter.Type, new object[] { actionParam.IsOptional });
                    }
                }
            }

            // add the metadata convention and our action and entityset convention
            var conventions = new List <IODataRoutingConvention>();

            conventions.Add(new MetadataRoutingConvention());
            conventions.Add(new RoutingConvention(typeof(T), builder.ContainerName));

            // Map the model to an Odata Route at the prefix
            return(config.Routes.MapODataServiceRoute(routePrefix, routePrefix, model, pathHandler: new DefaultODataPathHandler(), routingConventions: conventions));
        }
Example #52
0
        /// <summary>
        /// Maps ODataService Route and registers routes for any controller actions that use a [Route] attribute
        /// </summary>
        /// <param name="config">The configuration.</param>
        public static void Register(HttpConfiguration config)
        {
            config.EnableCors(new Rock.Rest.EnableCorsFromOriginAttribute());
            config.Filters.Add(new Rock.Rest.Filters.ValidateAttribute());
            config.Filters.Add(new Rock.Rest.Filters.RockCacheabilityAttribute());
            config.Services.Replace(typeof(IExceptionLogger), new RockApiExceptionLogger());
            config.Services.Replace(typeof(IExceptionHandler), new RockApiExceptionHandler());
            config.Services.Replace(typeof(System.Web.Http.Dispatcher.IAssembliesResolver), new RockAssembliesResolver());

            // Configure the API to handle differences between v1 and v2 endpoints.
            config.Services.Replace(typeof(IActionValueBinder), new RockActionValueBinder());
            config.Services.Clear(typeof(ValueProviderFactory));
            config.Services.Add(typeof(ValueProviderFactory), new RockQueryStringValueProviderFactory());
            config.Services.Add(typeof(ValueProviderFactory), new RockRouteDataValueProviderFactory());

            config.Formatters.Insert(0, new Utility.ApiPickerJsonMediaTypeFormatter());

            // register Swagger and its routes first
            Rock.Rest.Swagger.SwaggerConfig.Register(config);

            // Add API route for dataviews
            config.Routes.MapHttpRoute(
                name: "DataViewApi",
                routeTemplate: "api/{controller}/DataView/{id}",
                defaults: new
            {
                action = "DataView"
            });

            config.Routes.MapHttpRoute(
                name: "FollowedItemsApi",
                routeTemplate: "api/{controller}/FollowedItems",
                defaults: new
            {
                action = "FollowedItems"
            });

            config.Routes.MapHttpRoute(
                name: "InDataViewApi",
                routeTemplate: "api/{controller}/InDataView/{dataViewId}/{entityId}",
                defaults: new
            {
                action = "InDataView"
            });

            // Add API route for Launching a Workflow
            config.Routes.MapHttpRoute(
                name: "LaunchWorkflowApi",
                routeTemplate: "api/{controller}/LaunchWorkflow/{id}",
                defaults: new
            {
                action = "LaunchWorkflow"
            },
                constraints: new
            {
                httpMethod = new HttpMethodConstraint(new string[] { "POST" }),
            });

            // Add API route for DeleteAttributeValue
            config.Routes.MapHttpRoute(
                name: "DeleteAttributeValueApi",
                routeTemplate: "api/{controller}/AttributeValue/{id}",
                defaults: new
            {
                action = "DeleteAttributeValue"
            },
                constraints: new
            {
                httpMethod = new HttpMethodConstraint(new string[] { "DELETE" }),
            });

            // Add API route for SetAttributeValue
            config.Routes.MapHttpRoute(
                name: "SetAttributeValueApi",
                routeTemplate: "api/{controller}/AttributeValue/{id}",
                defaults: new
            {
                action = "SetAttributeValue"
            },
                constraints: new
            {
                httpMethod = new HttpMethodConstraint(new string[] { "POST" }),
            });

            // Add API route for setting context
            config.Routes.MapHttpRoute(
                name: "SetContextApi",
                routeTemplate: "api/{controller}/SetContext/{id}",
                defaults: new
            {
                action = "SetContext"
            },
                constraints: new
            {
                httpMethod = new HttpMethodConstraint(new string[] { "PUT", "OPTIONS" }),
            });

            // Add any custom HTTP API routes. Do this before the attribute route mapping to allow
            // derived classes to override the parent class route attributes.
            foreach (var type in Reflection.FindTypes(typeof(IHasCustomHttpRoutes)))
            {
                try
                {
                    var controller = Activator.CreateInstance(type.Value) as IHasCustomHttpRoutes;
                    if (controller != null)
                    {
                        controller.AddRoutes(config.Routes);
                    }
                }
                catch
                {
                    // ignore, and skip adding routes if the controller raises an exception
                }
            }

            // finds all [Route] attributes on REST controllers and creates the routes
            config.MapHttpAttributeRoutes();

            //// Add Default API Service routes
            //// Instead of being able to use one default route that gets action from http method, have to
            //// have a default route for each method so that other actions do not match the default (i.e. DataViews).
            //// Also, this will make controller routes case-insensitive (vs the odata routing)
            config.Routes.MapHttpRoute(
                name: "DefaultApiGetByAttributeValue",
                routeTemplate: "api/{controller}/GetByAttributeValue",
                defaults: new
            {
                action = "GetByAttributeValue"
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "GET", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            // Add GetByCampus API methods for controllers of types that implement ICampusFilterable
            foreach (var type in Reflection.FindTypes(typeof(Rock.Data.ICampusFilterable)))
            {
                try
                {
                    Type   typeValue      = ( Type )type.Value;
                    string pluralizedName = typeValue.Name.Pluralize();

                    config.Routes.MapHttpRoute(
                        name: $"Api{pluralizedName}GetByCampus",
                        routeTemplate: $"api/{pluralizedName}/GetByCampus",
                        defaults: new
                    {
                        action     = "GetByCampus",
                        controller = pluralizedName
                    },
                        constraints: new
                    {
                        httpMethod     = new HttpMethodConstraint(new string[] { "GET", "OPTIONS" }),
                        controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
                    });
                }
                catch
                {
                    // ignore, and skip adding routes if the controller raises an exception
                }
            }

            config.Routes.MapHttpRoute(
                name: "DefaultApiGetById",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
            {
                action = "GetById"
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "GET", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiGetFunction",
                routeTemplate: "api/{controller}({key})",
                defaults: new
            {
                action = "GET"
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "GET", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiGetList",
                routeTemplate: "api/{controller}",
                defaults: new
            {
                action = "GET"
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "GET", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiPut",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
            {
                action = "PUT",
                id     = System.Web.Http.RouteParameter.Optional
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "PUT", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiPatch",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
            {
                action = "PATCH",
                id     = System.Web.Http.RouteParameter.Optional
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "PATCH", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiPost",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
            {
                action         = "POST",
                id             = System.Web.Http.RouteParameter.Optional,
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            },
                constraints: new
            {
                httpMethod = new HttpMethodConstraint(new string[] { "POST", "OPTIONS" })
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiDelete",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
            {
                action = "DELETE",
                id     = System.Web.Http.RouteParameter.Optional
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "DELETE", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            // build OData model and create service route (mainly for metadata)
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder(config);

            var entityTypeList = Reflection.FindTypes(typeof(Rock.Data.IEntity))
                                 .Where(a => !a.Value.IsAbstract && (a.Value.GetCustomAttribute <NotMappedAttribute>() == null) && (a.Value.GetCustomAttribute <DataContractAttribute>() != null))
                                 .OrderBy(a => a.Key).Select(a => a.Value);

            foreach (var entityType in entityTypeList)
            {
                var entityTypeConfig = builder.AddEntity(entityType);

                var    tableAttribute = entityType.GetCustomAttribute <TableAttribute>();
                string name;
                if (tableAttribute != null)
                {
                    name = tableAttribute.Name.Pluralize();
                }
                else
                {
                    name = entityType.Name.Pluralize();
                }

                var entitySetConfig = builder.AddEntitySet(name, entityTypeConfig);
            }

            var defaultConventions = ODataRoutingConventions.CreateDefault();
            // Disable the api/$metadata route
            var conventions = defaultConventions.Except(defaultConventions.OfType <MetadataRoutingConvention>());

            config.Routes.MapODataServiceRoute("api", "api", builder.GetEdmModel(), pathHandler: new DefaultODataPathHandler(), routingConventions: conventions);


            new Rock.Transactions.RegisterControllersTransaction().Enqueue();
        }
Example #53
0
 /// <summary>
 /// 初始化OData服务模型
 /// </summary>
 /// <param name="builder"></param>
 public abstract void InitEdmModel(ODataConventionModelBuilder builder);
        public static IEdmModel BuildEdmModel(Type ApiContextType)
        {
            ODataModelBuilder builder = new ODataConventionModelBuilder();

            builder.Namespace = ApiContextType.Namespace;

            var publicProperties = ApiContextType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var property in publicProperties)
            {
                var entityClrType = TypeHelper.GetImplementedIEnumerableType(property.PropertyType);
                EntityTypeConfiguration entity = builder.AddEntityType(entityClrType);
                builder.AddEntitySet(property.Name, entity);
            }

            // Get the actions and functions into the model
            var publicMethods = ApiContextType.GetMethods(BindingFlags.Public | BindingFlags.Instance);

            foreach (var method in publicMethods)
            {
                if (!method.IsSpecialName)
                {
                    var entityClrType = TypeHelper.GetImplementedIEnumerableType(method.ReturnType) ?? method.ReturnType;
                    OperationConfiguration     configuration       = null;
                    PrimitiveTypeConfiguration primitiveEntityType = null;
                    EntityTypeConfiguration    entityType          = null;

                    if (entityClrType.IsQueryPrimitiveType())
                    {
                        primitiveEntityType = builder.AddPrimitiveType(entityClrType);
                    }
                    else
                    {
                        entityType = builder.AddEntityType(entityClrType);
                    }

                    var functionAttribute = method.GetCustomAttribute <ODataFunctionAttribute>();
                    if (functionAttribute != null)
                    {
                        configuration = builder.Function(method.Name);
                        if (functionAttribute.IsBound)
                        {
                            configuration.SetBindingParameterImplementation(functionAttribute.BindingName, entityType);
                        }
                    }

                    var actionAttribute = method.GetCustomAttribute <ODataActionAttribute>();
                    if (actionAttribute != null)
                    {
                        configuration = builder.Action(method.Name);
                        if (actionAttribute.IsBound)
                        {
                            configuration.SetBindingParameterImplementation(actionAttribute.BindingName, entityType);
                        }
                    }

                    if (configuration != null)
                    {
                        if (primitiveEntityType == null)
                        {
                            configuration.ReturnType = entityType;
                        }
                        else
                        {
                            configuration.ReturnType = primitiveEntityType;
                        }

                        configuration.IsComposable     = true;
                        configuration.NavigationSource =
                            builder.NavigationSources.FirstOrDefault(n => n.EntityType == entityType) as NavigationSourceConfiguration;

                        foreach (var parameterInfo in method.GetParameters())
                        {
                            if (parameterInfo.ParameterType.IsQueryPrimitiveType())
                            {
                                var primitiveType = builder.AddPrimitiveType(parameterInfo.ParameterType);
                                configuration.AddParameter(parameterInfo.Name, primitiveType);
                            }
                            else
                            {
                                if (parameterInfo.ParameterType.IsCollection())
                                {
                                    if (parameterInfo.ParameterType.GenericTypeArguments[0].GetTypeInfo().IsPrimitive)
                                    {
                                        var parameterType        = builder.AddPrimitiveType(parameterInfo.ParameterType.GenericTypeArguments[0]);
                                        var collectionTypeConfig = new CollectionTypeConfiguration(parameterType, parameterInfo.ParameterType.GenericTypeArguments[0]);
                                        configuration.AddParameter(parameterInfo.Name, collectionTypeConfig);
                                    }
                                    else
                                    {
                                        var parameterType        = builder.AddEntityType(parameterInfo.ParameterType.GenericTypeArguments[0]);
                                        var collectionTypeConfig = new CollectionTypeConfiguration(parameterType, parameterInfo.ParameterType.GenericTypeArguments[0]);
                                        configuration.AddParameter(parameterInfo.Name, collectionTypeConfig);
                                    }
                                }
                                else
                                {
                                    var parameterType = builder.AddEntityType(parameterInfo.ParameterType);
                                    configuration.AddParameter(parameterInfo.Name, parameterType);
                                }
                            }
                        }
                    }
                }
            }

            return(builder.GetEdmModel());
        }
        /// <summary>
        /// Maps ODataService Route and registers routes for any controller actions that use a [Route] attribute
        /// </summary>
        /// <param name="config">The configuration.</param>
        public static void Register(HttpConfiguration config)
        {
            config.EnableCors(new Rock.Rest.EnableCorsFromOriginAttribute());
            config.Filters.Add(new Rock.Rest.Filters.ValidateAttribute());
            config.Services.Replace(typeof(IExceptionLogger), new RockApiExceptionLogger());
            config.Services.Replace(typeof(IExceptionHandler), new RockApiExceptionHandler());
            config.Formatters.Insert(0, new Rock.Utility.RockJsonMediaTypeFormatter());

            // Add API route for dataviews
            config.Routes.MapHttpRoute(
                name: "DataViewApi",
                routeTemplate: "api/{controller}/DataView/{id}",
                defaults: new
            {
                action = "DataView"
            });

            // finds all [Route] attributes on REST controllers and creates the routes
            config.MapHttpAttributeRoutes();

            // Add any custom api routes
            foreach (var type in Rock.Reflection.FindTypes(
                         typeof(Rock.Rest.IHasCustomRoutes)))
            {
                try
                {
                    var controller = (Rock.Rest.IHasCustomRoutes)Activator.CreateInstance(type.Value);
                    if (controller != null)
                    {
                        controller.AddRoutes(RouteTable.Routes);
                    }
                }
                catch
                {
                    // ignore, and skip adding routes if the controller raises an exception
                }
            }

            //// Add Default API Service routes
            //// Instead of being able to use one default route that gets action from http method, have to
            //// have a default route for each method so that other actions do not match the default (i.e. DataViews).
            //// Also, this will make controller routes case-insensitive (vs the odata routing)
            config.Routes.MapHttpRoute(
                name: "DefaultApiGetById",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
            {
                action = "GetById"
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "GET", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiGetFunction",
                routeTemplate: "api/{controller}({key})",
                defaults: new
            {
                action = "GET"
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "GET", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiGetList",
                routeTemplate: "api/{controller}",
                defaults: new
            {
                action = "GET"
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "GET", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiPut",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
            {
                action = "PUT",
                id     = System.Web.Http.RouteParameter.Optional
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "PUT", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiPost",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
            {
                action         = "POST",
                id             = System.Web.Http.RouteParameter.Optional,
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            },
                constraints: new
            {
                httpMethod = new HttpMethodConstraint(new string[] { "POST", "OPTIONS" })
            });

            config.Routes.MapHttpRoute(
                name: "DefaultApiDelete",
                routeTemplate: "api/{controller}/{id}",
                defaults: new
            {
                action = "DELETE",
                id     = System.Web.Http.RouteParameter.Optional
            },
                constraints: new
            {
                httpMethod     = new HttpMethodConstraint(new string[] { "DELETE", "OPTIONS" }),
                controllerName = new Rock.Rest.Constraints.ValidControllerNameConstraint()
            });

            // build OData model and create service route (mainly for metadata)
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            var entityTypeList = Reflection.FindTypes(typeof(Rock.Data.IEntity))
                                 .Where(a => !a.Value.IsAbstract && (a.Value.GetCustomAttribute <NotMappedAttribute>() == null) && (a.Value.GetCustomAttribute <DataContractAttribute>() != null))
                                 .OrderBy(a => a.Key).Select(a => a.Value);

            foreach (var entityType in entityTypeList)
            {
                var entityTypeConfig = builder.AddEntity(entityType);
                var entitySetConfig  = builder.AddEntitySet(entityType.Name.Pluralize(), entityTypeConfig);
            }

            config.Routes.MapODataServiceRoute("api", "api", builder.GetEdmModel());
        }
        public static IEdmModel GetEdmModel(ODataConventionModelBuilder builder)
        {
            builder.EntitySet <ConventionCustomer>("ConventionCustomers");
            builder.EntitySet <ConventionOrder>("ConventionOrders");

            EnumTypeConfiguration <ConventionGender> enumType = builder.EnumType <ConventionGender>();

            enumType.Member(ConventionGender.Female);
            enumType.Member(ConventionGender.Male);
            #region functions

            FunctionConfiguration getAllCustomers = builder.Function("GetAllConventionCustomers");
            getAllCustomers.ReturnsCollectionFromEntitySet <ConventionCustomer>("ConventionCustomers");
            getAllCustomers.IsComposable = true;

            // Return all the customers whose name contains CustomerName
            FunctionConfiguration getAllCustomersOverload = builder.Function("GetAllConventionCustomers");
            getAllCustomersOverload.ReturnsCollectionFromEntitySet <ConventionCustomer>("ConventionCustomers");
            getAllCustomersOverload.Parameter <string>("CustomerName");
            getAllCustomersOverload.IsComposable = true;

            FunctionConfiguration getCustomersById = builder.Function("GetConventionCustomerById");
            getCustomersById.Parameter <int>("CustomerId");
            getCustomersById.ReturnsFromEntitySet <ConventionCustomer>("ConventionCustomers");
            getCustomersById.IsComposable = true;

            FunctionConfiguration getOrder = builder.Function("GetConventionOrderByCustomerIdAndOrderName");
            getOrder.Parameter <int>("CustomerId");
            getOrder.Parameter <string>("OrderName");
            getOrder.ReturnsFromEntitySet <ConventionOrder>("ConventionOrders");

            FunctionConfiguration getCustomerNameById = builder.Function("GetConventionCustomerNameById");
            getCustomerNameById.Parameter <int>("CustomerId");
            getCustomerNameById.Returns <string>();

            FunctionConfiguration getDefinedGenders = builder.Function("GetDefinedGenders");
            getDefinedGenders.ReturnsCollection <ConventionGender>()
            .IsComposable = true;

            FunctionConfiguration function = builder.Function("AdvancedFunction").Returns <bool>();
            function.CollectionParameter <int>("nums");
            function.CollectionParameter <ConventionGender>("genders");
            function.Parameter <ConventionAddress>("location");
            function.CollectionParameter <ConventionAddress>("addresses");
            function.EntityParameter <ConventionCustomer>("customer");
            function.CollectionEntityParameter <ConventionCustomer>("customers");

            #endregion

            #region actions

            ActionConfiguration resetDataSource = builder.Action("ResetDataSource");

            // bug: error message:  non-binding parameter type must be either Primitive, Complex, Collection of Primitive or a Collection of Complex.

            /*
             * ActionConfiguration createCustomer = builder.Action("CreateCustomer");
             * createCustomer.Parameter<ConventionCustomer>("Customer");
             * createCustomer.ReturnsFromEntitySet<ConventionCustomer>("ConventionCustomers");
             */

            ActionConfiguration udpateAddress = builder.Action("UpdateAddress");
            udpateAddress.Parameter <ConventionAddress>("Address");
            udpateAddress.Parameter <int>("ID");
            udpateAddress.ReturnsCollectionFromEntitySet <ConventionCustomer>("ConventionCustomers");

            ActionConfiguration action = builder.Action("AdvancedAction");
            action.CollectionParameter <int>("nums");
            action.CollectionParameter <ConventionGender>("genders");
            action.Parameter <ConventionAddress>("location");
            action.CollectionParameter <ConventionAddress>("addresses");
            action.EntityParameter <ConventionCustomer>("customer");
            action.CollectionEntityParameter <ConventionCustomer>("customers");

            #endregion

            var schemaNamespace = typeof(ConventionCustomer).Namespace;

            builder.Namespace = schemaNamespace;

            var edmModel  = builder.GetEdmModel();
            var container = edmModel.EntityContainer as EdmEntityContainer;

            #region function imports

            var entitySet = container.FindEntitySet("ConventionCustomers");
            var getCustomersByIdOfEdmFunction = edmModel.FindDeclaredOperations(schemaNamespace + ".GetConventionCustomerById").First() as EdmFunction;
            container.AddFunctionImport("GetConventionCustomerByIdImport", getCustomersByIdOfEdmFunction, new EdmPathExpression(entitySet.Name));

            var functionsOfGetAllConventionCustomers   = edmModel.FindDeclaredOperations(schemaNamespace + ".GetAllConventionCustomers");
            var getAllConventionCustomersOfEdmFunction = functionsOfGetAllConventionCustomers.FirstOrDefault(f => f.Parameters.Count() == 0) as EdmFunction;
            container.AddFunctionImport("GetAllConventionCustomersImport", getAllConventionCustomersOfEdmFunction, new EdmPathExpression(entitySet.Name));

            // TODO delete this overload after bug 1640 is fixed: It can not find the correct overload function if the the function is exposed as a function import.
            var getAllConventionCustomersOverloadOfEdmFunction = functionsOfGetAllConventionCustomers.FirstOrDefault(f => f.Parameters.Count() > 0) as EdmFunction;
            container.AddFunctionImport("GetAllConventionCustomersImport", getAllConventionCustomersOverloadOfEdmFunction, new EdmPathExpression(entitySet.Name));

            var entitySet1 = container.FindEntitySet("ConventionOrders");
            var GetConventionOrderByCustomerIdAndOrderNameOfEdmFunction = edmModel.FindDeclaredOperations(schemaNamespace + ".GetConventionOrderByCustomerIdAndOrderName").First() as EdmFunction;
            container.AddFunctionImport("GetConventionOrderByCustomerIdAndOrderNameImport", GetConventionOrderByCustomerIdAndOrderNameOfEdmFunction, new EdmPathExpression(entitySet1.Name));

            var getConventionCustomerNameByIdOfEdmFunction = edmModel.FindDeclaredOperations(schemaNamespace + ".GetConventionCustomerNameById").First() as EdmFunction;
            container.AddFunctionImport("GetConventionCustomerNameByIdImport", getConventionCustomerNameByIdOfEdmFunction, null);

            #endregion

            #region action imports

            var resetDataSourceOfEdmAction = edmModel.FindDeclaredOperations(schemaNamespace + ".ResetDataSource").FirstOrDefault() as EdmAction;
            container.AddActionImport("ResetDataSourceImport", resetDataSourceOfEdmAction);

            // TODO: it is a potential issue that entity can not be used as an un-bound parameter.

            /*
             * var createCustomerOfEdmAction = edmModel.FindDeclaredOperations(schemaNamespace + ".CreateCustomer").FirstOrDefault() as EdmAction;
             * container.AddActionImport("CreateCustomerImport", createCustomerOfEdmAction);
             */
            var updateAddressOfEdmAction = edmModel.FindDeclaredOperations(schemaNamespace + ".UpdateAddress").FirstOrDefault() as EdmAction;
            container.AddActionImport("UpdateAddressImport", updateAddressOfEdmAction, new EdmPathExpression(entitySet.Name));

            #endregion

            return(edmModel);
        }
        private static IEdmModel GetModel()
        {
            //var config = RoutingConfigurationFactory.CreateWithTypes(typeof(Customer));
            ODataModelBuilder builder = new ODataConventionModelBuilder();

            builder.ContainerName = "C";
            builder.Namespace     = "A.B";
            EntityTypeConfiguration <Customer> customer = builder.EntitySet <Customer>("Customers").EntityType;

            // bound actions
            ActionConfiguration primitive = customer.Action("Primitive");

            primitive.Parameter <int>("Quantity");
            primitive.Parameter <string>("ProductCode");
            primitive.Parameter <Date>("Birthday");
            primitive.Parameter <AColor>("BkgColor");
            primitive.Parameter <AColor?>("InnerColor");

            ActionConfiguration complex = customer.Action("Complex");

            complex.Parameter <int>("Quantity");
            complex.Parameter <MyAddress>("Address");

            ActionConfiguration enumType = customer.Action("Enum");

            enumType.Parameter <AColor>("Color");

            ActionConfiguration primitiveCollection = customer.Action("PrimitiveCollection");

            primitiveCollection.Parameter <string>("Name");
            primitiveCollection.CollectionParameter <int>("Ratings");
            primitiveCollection.CollectionParameter <TimeOfDay>("Time");
            primitiveCollection.CollectionParameter <AColor?>("Colors");

            ActionConfiguration complexCollection = customer.Action("ComplexCollection");

            complexCollection.Parameter <string>("Name");
            complexCollection.CollectionParameter <MyAddress>("Addresses");

            ActionConfiguration enumCollection = customer.Action("EnumCollection");

            enumCollection.CollectionParameter <AColor>("Colors");

            ActionConfiguration entity = customer.Action("Entity");

            entity.Parameter <int>("Id");
            entity.EntityParameter <Customer>("Customer");
            entity.EntityParameter <Customer>("NullableCustomer");

            ActionConfiguration entityCollection = customer.Action("EntityCollection");

            entityCollection.Parameter <int>("Id");
            entityCollection.CollectionEntityParameter <Customer>("Customers");

            // unbound actions
            ActionConfiguration unboundPrimitive = builder.Action("UnboundPrimitive");

            unboundPrimitive.Parameter <int>("Quantity");
            unboundPrimitive.Parameter <string>("ProductCode");
            unboundPrimitive.Parameter <Date>("Birthday");
            unboundPrimitive.Parameter <AColor>("BkgColor");
            unboundPrimitive.Parameter <AColor?>("InnerColor");

            ActionConfiguration unboundComplex = builder.Action("UnboundComplex");

            unboundComplex.Parameter <int>("Quantity");
            unboundComplex.Parameter <MyAddress>("Address");

            ActionConfiguration unboundEnum = builder.Action("UnboundEnum");

            unboundEnum.Parameter <AColor>("Color");

            ActionConfiguration unboundPrimitiveCollection = builder.Action("UnboundPrimitiveCollection");

            unboundPrimitiveCollection.Parameter <string>("Name");
            unboundPrimitiveCollection.CollectionParameter <int>("Ratings");
            unboundPrimitiveCollection.CollectionParameter <TimeOfDay>("Time");
            unboundPrimitiveCollection.CollectionParameter <AColor?>("Colors");

            ActionConfiguration unboundComplexCollection = builder.Action("UnboundComplexCollection");

            unboundComplexCollection.Parameter <string>("Name");
            unboundComplexCollection.CollectionParameter <MyAddress>("Addresses");

            ActionConfiguration unboundEnumCollection = builder.Action("UnboundEnumCollection");

            unboundEnumCollection.CollectionParameter <AColor>("Colors");

            ActionConfiguration unboundEntity = builder.Action("UnboundEntity");

            unboundEntity.Parameter <int>("Id");
            unboundEntity.EntityParameter <Customer>("Customer").Nullable = false;
            unboundEntity.EntityParameter <Customer>("NullableCustomer");

            ActionConfiguration unboundEntityCollection = builder.Action("UnboundEntityCollection");

            unboundEntityCollection.Parameter <int>("Id");
            unboundEntityCollection.CollectionEntityParameter <Customer>("Customers");

            return(builder.GetEdmModel());
        }
Example #58
0
        private static IEdmModel GetEdmModel()
        {
            var b = new ODataConventionModelBuilder();

            return(b.GetEdmModel());
        }
Example #59
0
        // Builds the EDM model for the OData service, including the OData action definitions.
        private static IEdmModel GetModel()
        {
            ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
            var moviesEntitySet            = modelBuilder.EntitySet <Movie>("Movies");

            moviesEntitySet.EntityType.Ignore(m => m.TimeStamp);    // Don't expose timestamp to clients

            // Now add actions to the EDM.

            // CheckOut
            // URI: ~/odata/Movies(1)/CheckOut
            // Transient action. It is not available when the item is already checked out.
            ActionConfiguration checkout = modelBuilder.Entity <Movie>().TransientAction("CheckOut");

            // Provide a function that returns a link to the action, when the action is available, or
            // returns null when the action is not available.
            checkout.HasActionLink(ctx =>
            {
                Movie movie = ctx.EntityInstance as Movie;

                // Note: In some cases, checking whether the action is available may be relatively expensive.
                // For example, it might require a DB lookup.

                // Avoid doing expensive checks inside a loop (i.e., when serializing a feed). Instead, simply
                // mark the action as available, by returning an action link.

                // The SkipExpensiveAvailabilityChecks flag says whether to skip expensive checks. If this flag
                // is true AND your availability check is expensive, skip the check and return a link.

                // In this sample, the check is not really expensive, but we honor the flag to show how it works.
                bool createLink = true;
                if (ctx.SkipExpensiveAvailabilityChecks)
                {
                    // Caller asked us to skip the availability check.
                    createLink = true;
                }
                else if (!movie.IsCheckedOut) // Here is the "expensive" check
                {
                    createLink = true;
                }

                if (createLink)
                {
                    // Return the URI of the action.
                    return(new Uri(ctx.Url.ODataLink(
                                       new EntitySetPathSegment(ctx.EntitySet),
                                       new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(movie.ID, ODataVersion.V3)),
                                       new ActionPathSegment(checkout.Name))));
                }
                else
                {
                    return(null);
                }
            }, followsConventions: true);   // "followsConventions" means the action follows OData conventions.
            checkout.ReturnsFromEntitySet <Movie>("Movies");

            // ReturnMovie
            // URI: ~/odata/Movies(1)/Return
            // Always bindable. If the movie is not checked out, the action is a no-op.
            // Binds to a single entity; no parameters.
            var returnAction = modelBuilder.Entity <Movie>().Action("Return");

            returnAction.ReturnsFromEntitySet <Movie>("Movies");

            // SetDueDate action
            // URI: ~/odata/Movies(1)/SetDueDate
            // Binds to a single entity; takes an action parameter.
            var setDueDate = modelBuilder.Entity <Movie>().Action("SetDueDate");

            setDueDate.Parameter <DateTime>("DueDate");
            setDueDate.ReturnsFromEntitySet <Movie>("Movies");

            // CheckOut action
            // URI: ~/odata/Movies/CheckOut
            // Shows how to bind to a collection, instead of a single entity.
            // This action also accepts $filter queries. For example:
            //     ~/odata/Movies/CheckOut?$filter=Year eq 2005
            var checkOutFromCollection = modelBuilder.Entity <Movie>().Collection.Action("CheckOut");

            checkOutFromCollection.ReturnsCollectionFromEntitySet <Movie>("Movies");

            // CheckOutMany action
            // URI: ~/odata/Movies/CheckOutMany
            // Shows an action that takes a collection parameter.
            ActionConfiguration checkoutMany = modelBuilder.Entity <Movie>().Collection.Action("CheckOutMany");

            checkoutMany.CollectionParameter <int>("MovieIDs");
            checkoutMany.ReturnsCollectionFromEntitySet <Movie>("Movies");

            // CreateMovie action
            // URI: ~/odata/CreateMovie
            // Non-bindable action. You invoke it from the service root.
            ActionConfiguration createMovie = modelBuilder.Action("CreateMovie");

            createMovie.Parameter <string>("Title");
            createMovie.ReturnsFromEntitySet <Movie>("Movies");

            return(modelBuilder.GetEdmModel());
        }
Example #60
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            var provider = app.ApplicationServices.GetRequiredService <IAssemblyProvider>();

            app.UseCors(builder =>
                        builder.WithOrigins("*")
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials()
                        .AllowAnyOrigin()
                        );

            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey         = TokenProviderOptions.Key,
                ValidateIssuer           = true,
                ValidIssuer      = TokenProviderOptions.Issuer,
                ValidateAudience = true,
                ValidAudience    = TokenProviderOptions.Audience,
                ValidateLifetime = true,
                ClockSkew        = TimeSpan.Zero
            };

            var options = new JwtBearerOptions
            {
                AutomaticAuthenticate     = true,
                AutomaticChallenge        = true,
                TokenValidationParameters = tokenValidationParameters
            };

            app.UseJwtBearerAuthentication(options);

            app.Use(async(context, next) => {
                try
                {
                    await next();
                }
#pragma warning disable 0168
                catch (Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException ex) {
#pragma warning restore 0168
                    if (!Path.HasExtension(context.Request.Path.Value))
                    {
                        context.Request.Path = "/index.html";
                        await next();
                    }
                }

                if ((context.Response.StatusCode == 404 || context.Response.StatusCode == 401) && !Path.HasExtension(context.Request.Path.Value))
                {
                    context.Request.Path = "/index.html";
                    await next();
                }
            });

            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseDeveloperExceptionPage();

            app.UseMvc(builder =>
            {
                if (env.EnvironmentName == "Development")
                {
                    builder.MapRoute(name: "default",
                                     template: "{controller}/{action}/{id?}",
                                     defaults: new { controller = "Home", action = "Index" }
                                     );
                }
                var agriculturebdBuilder           = new ODataConventionModelBuilder(provider);
                agriculturebdBuilder.ContainerName = "AgriculturebdContext";

                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Calidad>("Calidads");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.CategoriaInsumo>("CategoriaInsumos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Categorium>("Categoria");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Ciudad>("Ciudads");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Compra>("Compras");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.ComprasPago>("ComprasPagos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.ControlPlaga>("ControlPlagas");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Cultivo>("Cultivos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Departamento>("Departamentos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.DetalleCategoriaInsumo>("DetalleCategoriaInsumos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.DetalleCompra>("DetalleCompras");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.DetalleMetodopago>("DetalleMetodopagos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.DetalleOfertum>("DetalleOferta");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.DetalleTipoProducto>("DetalleTipoProductos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Enfermedade>("Enfermedades");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Equipo>("Equipos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Foto>("Fotos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Insumo>("Insumos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Laboratorio>("Laboratorios");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.LocalizacionUp>("LocalizacionUps");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Lote>("Lotes");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.MetodoPago>("MetodoPagos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Notificacione>("Notificaciones");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Oferta>("Oferta");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Pago>("Pagos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Produccion>("Produccions");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.ProductCategorium>("ProductCategoria");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Producto>("Productos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Recetum>("Receta");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Rol>("Rols");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.TipoInsumo>("TipoInsumos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.TipoProducto>("TipoProductos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Tratamiento>("Tratamientos");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.TypeNotification>("TypeNotifications");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.UnidadMedida>("UnidadMedidas");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.UnidadProductiva>("UnidadProductivas");
                agriculturebdBuilder.EntitySet <Agriculturapp.Models.Agriculturebd.Usuario>("Usuarios");

                builder.MapODataRoute("odata/agriculturebd", agriculturebdBuilder.GetEdmModel());
                var identityBuilder           = new ODataConventionModelBuilder(provider);
                identityBuilder.ContainerName = "ApplicationIdentityDbContext";
                identityBuilder.EntitySet <ApplicationUser>("ApplicationUsers");
                var usersType = identityBuilder.StructuralTypes.First(x => x.ClrType == typeof(ApplicationUser));
                usersType.AddCollectionProperty(typeof(ApplicationUser).GetProperty("RoleNames"));
                identityBuilder.EntitySet <IdentityRole>("ApplicationRoles");

                builder.MapODataRoute("auth", identityBuilder.GetEdmModel());
            });

            var identityDbContext = app.ApplicationServices.GetRequiredService <ApplicationIdentityDbContext>();

            identityDbContext.Database.Migrate();

            OnConfigure(app);
        }