Generic Controller not working

Open
#737 10 comments 0 reactions 1 assignee View on GitHub

@xuzhg is already working on this.

Since Nov 15, 2022.

Assessment

This issue has not been assessed yet.

Description

bug documentation investigated

Currently using 8.0.11

Return response not being formatted to odata response IE not including @odata.Context
Actual Result
image
Expected Result
image

Reproduce steps

In Main during the builder process
            ODataConventionModelBuilder odataBuilder = new ODataConventionModelBuilder();
            odataBuilder.EntitySet<TestObj>("TestObj");

            builder.Services.AddControllersWithViews()
               .AddOData(options =>
               {
                   options.EnableQueryFeatures();
                   options.AddRouteComponents("api/odata", odataBuilder.GetEdmModel());
               })
               .ConfigureApplicationPartManager(pm =>
               {
                   pm.FeatureProviders.Add(new TestProvider());
               })
               .AddODataNewtonsoftJson()
               .AddNewtonsoftJson();

###Model / Controller setup

public class TestObj
    {
        public int Id { get; set; }
        public string? Name { get; set; }
    }

    [GenericControllerRouteConvention]
    public class OdataController<T> : ODataController
    {
        [HttpGet]
        [EnableQuery]
        public IQueryable<T> Get()
        {
            return (new List<T>()).AsQueryable();
        }
    }

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public class GenericControllerRouteConvention : Attribute, IControllerModelConvention
    {
        public void Apply(ControllerModel controller)
        {
            if (controller.ControllerType.IsGenericType)
            {
                Type? genericType = controller.ControllerType.GenericTypeArguments[0];

                var name = genericType.Name;

                controller.ControllerName = name + "Controller";
                controller.Selectors.Add(new SelectorModel
                {
                    AttributeRouteModel = new AttributeRouteModel(new RouteAttribute("api/odata/" + name)),
                });
            }
        }
    }

    public class TestProvider : IApplicationFeatureProvider<ControllerFeature>
    {
        public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
        {
            TypeInfo? controllerType = typeof(OdataController<>)
                 .MakeGenericType(typeof(TestObj)).GetTypeInfo();
            feature.Controllers.Add(controllerType);
        }
    }

EDM (CSDL) Model
image

Request/Response
https://localhost/api/odata/TestObj

Expected behavior
image

Additional context
I plan on using this to auto generate hundreds of odata endpoints and although this code is simple and only for one model it does reproduce the bug.

Everything works if I defined the controller explicitly
public class TestObjController : ODataController
but that is not a viable solution when you have hundreds of models.

Dominant language
C#
Stars
505
Forks
186
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from OData/AspNetCoreOData

All issues in OData/AspNetCoreOData

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.