这里我有三个继承自同一个 Controller 的 Controller 。
所有三个 Controller 都采用相同的配置。
当我进行以下查询时; https://localhost:7069/odata/人员 或者 https://localhost:7069/odata/员工 具有此签名的方法称为
public ActionResult<IQueryable<TModel>> Get(ODataQueryOptions<TModel> oDataQueryOptions)
这是预期的行为
问题
当我发出这个请求时 https://localhost:7069/odata/Staffs
调用的就是这个方法
public async Task<ActionResult<TModel>> Get(int id)
如果我删除 Get(int id) 方法。
调用的 Get(ODataQueryOptions oDataQueryOptions) 方法 一切正常
问题
问题从何而来?
设置我
这是基本 Controller 中的两个方法:
[HttpGet]
[EnableQuery(MaxExpansionDepth = 10, MaxNodeCount = 1000)]
public ActionResult<IQueryable<TModel>> Get(ODataQueryOptions<TModel> oDataQueryOptions)
{
modelService.ODataQueryOptions = oDataQueryOptions;
var result = modelService.GetModelsAsync().Result;
return Ok(result.Value);
}
[HttpGet("{id}")]
public async Task<ActionResult<TModel>> Get(int id)
{
var result = await modelService.GetModelAsync(id);
return OK(result);
}
Controller 继承:它们具有相同的配置:
[Route("api/[controller]")]
[ApiController]
public class EmployeesController : PersonCollectionControllerBase<EmployeeDto, EmployeesService>
{
public EmployeesController(IEmployeesService employeesService): base(employeesService)
{
}
}
[Route("api/[controller]")]
[ApiController]
public class PersonsController : PersonCollectionControllerBase<PersonDto, PersonsService>
{
public PersonsController(IPersonsService persons): base(persons)
{
}
}
[Route("api/[controller]")]
[ApiController]
public class StaffsController : PersonCollectionControllerBase<StaffDto, StaffsService>
{
public StaffsController(IStaffService modelService) : base(modelService)
{
}
}
IServiceCollection 配置:
builder.Services.AddControllers().AddOData(options =>
{
options.AddRouteComponents(routePrefix: "odata", GetEdmModel())
.Select().Count().Filter().Expand().OrderBy().SetMaxTop(maxTopValue: 100);
});
IEdm 配置:
public static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new();
builder.EntitySet<PersonDto>(name: "Person")
.EntityType.HasKey(person => person.BusinessEntityId);
builder.EntitySet<PersonDtoBase>(name: "PersonsBase")
.EntityType.HasKey(person => person.BusinessEntityId);
builder.EntitySet<EmployeeDto>(name: "Employees")
.EntityType.HasKey(employee => employee.BusinessEntityId);
builder.EntitySet<EmployeeDtoBase>(name: "EmployeesBase")
.EntityType.HasKey(employee => employee.BusinessEntityId);
builder.EntitySet<StaffDto>(name: "Staffs")
.EntityType.HasKey(staff => staff.BusinessEntityId);
return builder.GetEdmModel();
}
最佳答案
问题的原因是方法 Get(int id) 中的名称 id 及其属性 [HttpGet("{id}")] 必须将它们替换为键。
属性 [Route(“api/[Controller]”)], Controller 必须解释示例 [Route(“odata/staffs”)] 对任何使用 Odata 的 Controller 执行此操作,
另一件事,如果你想在 Route 属性中使用 Odata 和 Api 端点,将 odata 替换为 api 示例 [Route(“api/staffs”)]
此解决方案由 Juliano Leal Goncalves 在网站 https://github.com/OData/AspNetCoreOData/issues/664 中建议
关于c# - Controller 中有两种方法时的 API 和 OData 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73196984/