c# - Controller 中有两种方法时的 API 和 OData 行为

标签 c# api .net-core odata

这里我有三个继承自同一个 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/

相关文章:

api - 知识图 API 返回与站点不同的结果

api - 使用 google.loader.ClientLocation 获取用户位置对我有用,但对其他人无效

c# - WebAPI : Creating custom BadRequest status outside of ApiController

c# - 需要生成EDMX文件并编译

c# - 获取函数的 Ptr 值

c# - 如何访问在单独的类中声明的 ENUM - C#

c# - 使用小数估算计算误差

python - 我的代码正在处理字典列表,就像字符串一样,类型错误: TypeError: string indices must be integers

c# - 当启动多个控制台应用程序时,仅终止一个控制台应用程序

docker - 无法在 Docker 容器中为 ASP.NET Core Web App 创建开发证书