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()); }
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); } }
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(); }
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(); }
// 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); }
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); }
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(); }
private static IEdmModel GetSampleModel() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<Employee>("employees"); builder.EntitySet<WorkItem>("workitems"); return builder.GetEdmModel(); }
private IEdmModel GetEdmModel() { ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<Customer>("FormatCustomers"); builder.Singleton<Customer>("This"); // Singleton return builder.GetEdmModel(); }
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(); }
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(); }
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; }
partial void OnConfigureOData(ODataConventionModelBuilder builder);
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); }
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);
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"]); }
/// <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()); }
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);
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()); }
private static void ConfigureModelToSupportOdata(ODataConventionModelBuilder builder) { }
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))); }
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); }
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)); }
/// <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(); }
/// <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()); }
private static IEdmModel GetEdmModel() { var b = new ODataConventionModelBuilder(); return(b.GetEdmModel()); }
// 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()); }
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); }