I am using .Net Core 2.2 as my underlying framework here, so this information might not be inkeeping with how things are currently done (if so please, I welcome the feedback on how to put this right).
I have an Api App that initializes multiple OData contexts that happen to have some crossover in entity set names and thus controller names.
In this case I have a "Core" OData context + model and a "Members" context + model. the net result is that both of these OData models contains a Users entity set with controllers looking like this ...
[ODataRoutePrefix("Members/User")]
public class UserController : MembersEntityODataController<Members.User> { }
[ODataRoutePrefix("Core/User")]
public class UserController : CoreEntityODataController<Core.User> { }
... they essentially do the same job but refer to entities stored in the same table but in different databases. I can't seem to for the life of me figure out how to initialize / declare these controllers such that the routing actually works and instead all requests for both ~/Core/User and ~/Members/User result in a members user controller being passed on to handle the request.
My understanding is that this is the exact scenario that the ODataRoutePrefix attribute was built to solve (amongst others) and it doesn't seem to help here.
to make the process of adding new OData models to my API easier I wrapped up the model construction in my own model building but the net result is a core call to use odata during startup which looks like this ...
app.UseMvc(routeBuilder =>
{
routeBuilder.EnableDependencyInjection();
routeBuilder.MapRoute("default", "{controller=Home}/{action=Get}");
});
var builders = new ODataModelBuilder[] {
new MembersModelBuilder(),
new CoreModelBuilder(),
new B2BModelBuilder(),
new SearchModelBuilder()
};
foreach (var builder in builders)
{
var model = builder.Build();
app.UseOData(model.Context + "Api", builder.GetType().Name.Replace("ModelBuilder", ""), model.EDMModel);
}
Do I need to do something special here to make routing work as intended?
It does seem that this "type of scenario" has been considered before as I'm seeing things like this ... https://github.com/OData/WebApi/issues/1494 ... which talks about API versions ... my case isn't quite this, but it's close enough that I figure the same parts of the framework logic should apply (somewhat).
@xuzhg talks about the solution being to apply the ODataRoute Attribute on the Actions ...
[ODataRoute("Sensors", RouteName = "ODataRouteV1")]
public IActionResult Get()
[ODataRoute("Sensors", RouteName = "ODataRouteV2")]
public IActionResult Get()
... I need to do presumably be able to do the same thing at the controller level but alas this attribute cannot be used on classes only methods.
Obviously i'm sourcing my understanding from this ... https://docs.microsoft.com/en-us/odata/webapi/attribute-routing ... which talks about using the ODataRoutePrefix attribute to apply context to the routing engine for when a controller should be selected.
Have I hit an edge case here ?