Microsoft.AspNetCore.OData 8:控制器未按约定找到
Microsoft.AspNetCore.OData 8: controller is not found by convention
如演示此行为的 docs, Microsoft.AspNetCore.OData 8 uses a convention to tie a controller to an entity set. They also provide a sample 中所述。
然而,我花了几个小时用一个简单的控制器设置了一个最小的 OData API,但是控制器既没有显示在 OData 路由调试页面 ($odata) 上,也无法访问它通过浏览器。
这是型号:
namespace TestOData8
{
public class Dummy
{
public int Id { get; set; }
}
}
这是控制器:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;
namespace TestOData8.Controllers
{
public class DummiesController : ODataController
{
[HttpGet]
[EnableQuery]
public IActionResult Query(CancellationToken ct)
{
return Ok(Enumerable.Range(1, 10).Select(x => new Dummy() { Id = x }).AsQueryable());
}
}
}
此代码设置应用程序(这是 .NET 6 的设置方式;我也尝试过 .NET 5 但没有成功):
using Microsoft.AspNetCore.OData;
using Microsoft.OData.Edm;
using Microsoft.OData.ModelBuilder;
using TestOData8;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers()
.AddOData(opt => opt.Count().Filter().Expand().Select().OrderBy().SetMaxTop(5)
.AddRouteComponents(GetEdmModel())
);
IEdmModel GetEdmModel()
{
var bldr = new ODataConventionModelBuilder();
bldr.EntitySet<Dummy>("Dummies");
return bldr.GetEdmModel();
}
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
//app.UseAuthorization();
app.UseODataRouteDebug();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.Run();
我断言
- EDM 模型已注册(此 $metadata 端点显示虚拟实体)
- 控制器的名称与实体集匹配(Dummies -> DummiesController)
- 路由适用于不支持 OData 的控制器
- 将
EnableAttributeRouting
选项设置为 false 不会改变行为
我是什么missing/misunderstanding?
修复非常简单:控制器中方法的名称必须是“Get”;更改动作名称后,控制器工作:
public class DummiesController : ODataController
{
[HttpGet]
[EnableQuery]
public IActionResult Get(CancellationToken ct)
{
return Ok(Enumerable.Range(1, 10).Select(x => new Dummy() { Id = x }).AsQueryable());
}
}
感谢@JamesLove 在另一个 下的小评论。
如演示此行为的 docs, Microsoft.AspNetCore.OData 8 uses a convention to tie a controller to an entity set. They also provide a sample 中所述。
然而,我花了几个小时用一个简单的控制器设置了一个最小的 OData API,但是控制器既没有显示在 OData 路由调试页面 ($odata) 上,也无法访问它通过浏览器。
这是型号:
namespace TestOData8
{
public class Dummy
{
public int Id { get; set; }
}
}
这是控制器:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;
namespace TestOData8.Controllers
{
public class DummiesController : ODataController
{
[HttpGet]
[EnableQuery]
public IActionResult Query(CancellationToken ct)
{
return Ok(Enumerable.Range(1, 10).Select(x => new Dummy() { Id = x }).AsQueryable());
}
}
}
此代码设置应用程序(这是 .NET 6 的设置方式;我也尝试过 .NET 5 但没有成功):
using Microsoft.AspNetCore.OData;
using Microsoft.OData.Edm;
using Microsoft.OData.ModelBuilder;
using TestOData8;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers()
.AddOData(opt => opt.Count().Filter().Expand().Select().OrderBy().SetMaxTop(5)
.AddRouteComponents(GetEdmModel())
);
IEdmModel GetEdmModel()
{
var bldr = new ODataConventionModelBuilder();
bldr.EntitySet<Dummy>("Dummies");
return bldr.GetEdmModel();
}
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
//app.UseAuthorization();
app.UseODataRouteDebug();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.Run();
我断言
- EDM 模型已注册(此 $metadata 端点显示虚拟实体)
- 控制器的名称与实体集匹配(Dummies -> DummiesController)
- 路由适用于不支持 OData 的控制器
- 将
EnableAttributeRouting
选项设置为 false 不会改变行为
我是什么missing/misunderstanding?
修复非常简单:控制器中方法的名称必须是“Get”;更改动作名称后,控制器工作:
public class DummiesController : ODataController
{
[HttpGet]
[EnableQuery]
public IActionResult Get(CancellationToken ct)
{
return Ok(Enumerable.Range(1, 10).Select(x => new Dummy() { Id = x }).AsQueryable());
}
}
感谢@JamesLove 在另一个