Search code examples
asp.net-core-mvcodataasp.net-core-webapiasp.net-core-routingasp.net-core-configuration

OData Controller withing Asp.Net Core MVC application


I'm working on a project in ASP .NET Core 3.1 MVC now I want to add some API controllers to return list of objects. For this I want to use OData Controller version 8.0.0 so I can get quarriable data to improve performance on large data tables

I'm new in ASP .NET Core and OData. can anybody explain how to configure my project's Startup file so I can run both MVC and OData controllers same time. Kindly share some example code


Solution

  • I have managed to fix my issue to run Web Application which exposes OData APIs Issue was in Startup.cs file

    I'm using Asp.Net Core 3.1 and Microsoft.AspNetCore.OData v7.3.0

    my Startup.cs file code is:

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
    
    
            services.AddIdentity<AppUser, AppRole>(opt =>
            {
                opt.User.RequireUniqueEmail = true;
            })
                //.AddDefaultUI(UIFramework.Bootstrap4)
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();
    
            //add services
            services.RegisterServices();
    
            services.AddScoped<ViewRendererService>();
    
            services.AddMvc()
                .AddMvcOptions(options => options.EnableEndpointRouting = false)
                .AddNewtonsoftJson(options =>
                {
                    options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
                })
                .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
    
            services.AddOData();
    
            services.AddRouting();
            services.AddControllersWithViews();
            services.AddRazorPages();
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ApplicationDbContext dataContext)
        {
            if (env.EnvironmentName == "Development")
            {
                dataContext.Database.Migrate();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseDeveloperExceptionPage();
                app.UseHsts();
            }
    
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
    
            app.UseAuthentication();
    
            app.UseRequestLocalization();
    
            app.UseMvc(routes =>
            {
                routes.Select().Filter().OrderBy().Expand().Count().SkipToken().MaxTop(null);
                routes.MapODataServiceRoute("odata", "api", GetEdmModel());
                routes.MapRoute(
                    name: "areas",
                    template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
                );
    
                routes.MapRoute(
                    name: "Finance",
                    template: "{area:exists}/{controller=Account}/{action=Index}/{id?}"
                );
    
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
    
        }
        private static IEdmModel GetEdmModel()
        {
            var builder = new ODataConventionModelBuilder();
            builder.EntitySet<Product>("ProductApi");
            builder.EntitySet<ProductUOM>("ProductUomApi");
    
            ActionConfiguration action = builder.EntityType<Product>().Action("GetUOM");
            action.Parameter<long>("id");
            action.ReturnsCollectionFromEntitySet<Product>("Product");
    
            return builder.GetEdmModel();
        }
    }
    

    Hope this will help others