WebApi
WebApi copied to clipboard
ODataRoute template is not working in .Net Core
I was using ODataRoute with a template in .Net. I was working fine. Now, I am trying to migrate to .Net Core, but it is not working.
Assemblies affected
I am using Microsoft.AspNetCore.OData
Reproduce steps
My ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddOData();
services.AddRouting();
services.AddMvc();
}
Configuration:
public static void Configure(object appBuilder)
{
var app = appBuilder as IApplicationBuilder;
var builder = new ODataConventionModelBuilder(app.ApplicationServices);
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseODataBatching();
var edmModel = GetEdmModel(builder);
app.UseDeveloperExceptionPage();
app.UseEndpoints(routeBuilder =>
{
routeBuilder.EnableDependencyInjection();
routeBuilder.Select().Filter().Expand();
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);
});
});
}
static IEdmModel GetEdmModel(ODataConventionModelBuilder builder)
{
builder.EntityType<Student>().HasKey(a => a.Id);
builder.EntitySet<Student>("Student");
return builder.GetEdmModel();
}
Controller:
public class StudentController : BaseController<Student>
{
[EnableQuery]
[ODataRoute("Student(Id={key})")]
public override IActionResult Get(string key)
{
return Get("Id", key);
}
}
Expected result
Get method should work when I send query: https://localhost:44383/odata/Student(Id='DBS')*
Actual result
It is returning 404 when I send query https://localhost:44383/odata/Student(Id='DBS')*
Additional detail
It was working on .Net. Maybe it is happening because of workaround of https://github.com/OData/WebApi/issues/1622*
@komdil Can https://localhost:44383/odata/Student('DBS')
works at your side?
@xuzhg
@komdil Can
https://localhost:44383/odata/Student('DBS')
works at your side?
I tried, but I didn't work. Also, putting ODataRoutePrefix is not affecting to my controllers. I researched, but I couldn't find solution
@komdil, please note that your controllers should inherit from ODataController
. In your case you're inheriting from BaseController
(should it be ControllerBase
?).
While you can certainly use the ODataRoute
attribute, keep in mind that it's not necessary for Get(int key)
as it will map to Student({key})
automatically.
@komdil, please note that your controllers should inherit from
ODataController
. In your case you're inheriting fromBaseController
(should it beControllerBase
?).While you can certainly use the
ODataRoute
attribute, keep in mind that it's not necessary forGet(int key)
as it will map toStudent({key})
automatically.
@habbes Here is my BaseController class. It is inherited from ODataController:
` [ODataRoutePrefix("{contextToken}/[controller]")]
[ODataRoutePrefix("[controller]")]
public class BaseController<TEntity> : ODataController where TEntity : class
{
public IActionResult Get(ODataQueryOptions<TEntity> queryOptions, CancellationToken cancellationToken)
{
var list = new List<Student>
{
CreateNewStudent("Cody Allen", 130),
CreateNewStudent("Todd Ostermeier", 160),
CreateNewStudent("Viral Pandya", 140)
};
return Ok(list);
}
public virtual IActionResult Get(string key)
{
var list = new List<Student>
{
CreateNewStudent("Cody Allen", 130),
CreateNewStudent("Todd Ostermeier", 160),
CreateNewStudent("Viral Pandya", 140)
};
return Ok(list);
}
private static Student CreateNewStudent(string name, int score)
{
return new Student
{
Id = Guid.NewGuid(),
Name = name,
Score = score
};
}
}`
The purpose of putting [ODataRoutePrefix("{contextToken}/[controller]")] is I want to work with specific DB context by Guid. I am getting this token from Request.RouteValues["contextToken"]. I tried to do it in ASP.Net Core and it is working when I put [Route("{contextToken}/[controller]")] [Route("[controller]")] in controller. But ODataRoutePrefix is not afffecting on my controller
I had an issue, that an odata function with [ODataRoute] was not found (got 404). So I played around with MapODataRoute and in my opinion I experienced a pretty strange behavior.
You can see my experiments here: https://github.com/manureini/OData3.1WithSwagger/commit/3bb3d9e7196de49dbbeba98338a2413f971def3c
For me the routing only works when I use the magicFunc
variable. - I don't understand, why this is working 😕
@komdil could you share repro of your scenario. I'm curious about what your CustomODataRoutingConvention()
is doing. Could it be that it overrides the attribute routing convention?
I have the same issue with newest version Version="8.0.0-preview3" : https://stackoverflow.com/questions/65551331/using-odatarouteprefix-and-odataroute-for-odata-attributerouting-is-not-working
@komdil Was this issue resolved?
@komdil Was this issue resolved?
I don't know. Did you check the steps?
Closing this issue due to inactivity. If this issue still persists, feel free to create a new issue.