Search code examples
c#asp.net-core.net-coreodata

IContainerBuilder.AddService is not working in IRouteBuilder OData .Net Core in Adding EdmModel


I was using this part of code in OData .Net. This code is working in .Net Core. Here is my configuration class:

 public static class Configuration
    {
        public static Action<IApplicationBuilder> ConvertToAppBuilder(Action<object> myActionT)
        {
            if (myActionT == null) return null;
            else return new Action<object>(o => myActionT(o));
        }


        public static Action<IApplicationBuilder> GetBuilder()
        {
            return ConvertToAppBuilder(Configure);
        }

        public static void Configure(object appBuilder)
        {
            var app = appBuilder as IApplicationBuilder;
            var config = new RouteBuilder(app);
            var builder = new ODataConventionModelBuilder(config.ApplicationBuilder.ApplicationServices) { Namespace = "Model.Entities", ContainerName = "DefaultContainer" };

            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();

            app.UseMvc(routeBuilder =>
            {
                routeBuilder.Select().Filter();
                routeBuilder.MapODataServiceRoute("odata", "odata", configureAction: c => c
                .AddService(Microsoft.OData.ServiceLifetime.Transient, typeof(IEdmModel), sp => GetEdmModel()));
            });
        }

        static IEdmModel GetEdmModel()
        {
            var odataBuilder = new ODataConventionModelBuilder();
            odataBuilder.EntitySet<Student>("Student");

            return odataBuilder.GetEdmModel();
        }
    } 

It is working when I use the first constructor

 app.UseMvc(routeBuilder =>
        {
            routeBuilder.Select().Filter();
            routeBuilder.MapODataServiceRoute("odata", "odata", GetEdmModel());
        });

But I need to use the second constructor because I will add there custom ODataUriResolver. So how can I fix this issue?


Solution

  • I had the same problem. Seams source code has issue on adding custom convension. Following code worked on me:

     routeBuilder.MapODataRoute("OData", "odata", b =>
                {
                    b.AddService(Microsoft.OData.ServiceLifetime.Singleton, sp => edmModel);
                    var customRoutingConvention = new ODataCustomRoutingConvention();
                    var conventions = ODataRoutingConventions.CreateDefault();
                    //Workaround for https://github.com/OData/WebApi/issues/1622
                    conventions.Insert(0, new AttributeRoutingConvention("OData", app.ApplicationServices, new DefaultODataPathHandler()));
                    //Custom Convention
                    conventions.Insert(0, customRoutingConvention);
                    b.AddService<IEnumerable<IODataRoutingConvention>>(Microsoft.OData.ServiceLifetime.Singleton, a => conventions);
                });