控制器动作 HttpGet 执行错误的动作

Controller action HttpGet executes wrong action

我从 Visual Studio 模板创建了一个新的 Web API 项目,然后我按照以下教程将 OData 添加到该项目。 https://devblogs.microsoft.com/odata/supercharging-asp-net-core-api-with-odata/

打电话 https://localhost:xxx/api/Assetshttps://localhost:xxx/api/Assets/1

return 所有资产,而后者应该 return 只有 1 个资产(其中 id = 1)

我的代码:

public class AssetsController : ControllerBase
{
    private IAssetService _service;
    private IMapper _mapper;

    public AssetsController (IAssetService _service, IMapper mapper)
    {
        this._service = _service;
        this._mapper = mapper;
    }

    [HttpGet]
    [EnableQuery()]
    public ActionResult<IEnumerable<Asset>> Get()
    {
        return this._service.GetAllAssets().ToList();
    }


    [HttpGet("{id}")]
    [EnableQuery()]
    public Asset Get(int id)
    {
        return _service.GetById(id);
    }
}

我已调试以验证从未调用过 Get(int id) 函数。

我试过像这样明确定义我的路线:

[HttpGet]
[Route("GetById/{id}")]
[EnableQuery()]
public Asset Get(int id)
{
    return _service.GetById(id);
}

编辑

启动时定义的路由:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            /* snip */

            app.UseMvc(routeBuilder =>
            {
                routeBuilder.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");

                routeBuilder.Select().Filter().OrderBy().Expand().Count().MaxTop(10);
                routeBuilder.MapODataServiceRoute("api", "api", GetEdmModel());
            });

        }

这没有区别。

有什么想法吗?

这对我有用...

[HttpGet]
public ActionResult<IEnumerable<Asset>> Get()
{
    return this._service.GetAllAssets().ToList();
}


[HttpGet("{id}")]
public Asset Get(int id)
{
    return _service.GetById(id);
}

有两种方法可以解决这个问题。

方法 1:将 id 参数重命名为 key

根据 OData v4 Web API docs :

Here are some rules for the method signatures:

  • If the path contains a key, the action should have a parameter named key.
  • If the path contains a key into a navigation property, the action should have a > parameter named relatedKey.
  • POST and PUT requests take a parameter of the entity type.
  • PATCH requests take a parameter of type Delta, where T is the entity type.

我们应该有一个名为 key:

的参数
[HttpGet("{id}")]  // actually, this line doesn't matter if you're using OData, but it's better to rename it to `key` too
[EnableQuery()]
public IActionResult Get(int key)
{
    ....
}

方法二:将Get方法重命名为GetAsset

根据OData v4 Web API docs

When Web API gets an OData request, it maps the request to a controller name and an action name. The mapping is based on the HTTP method and the URI. For example, GET /odata/Products(1) maps to ProductsController.GetProduct.

我们还可以将操作方法​​重命名为 GetAsset,如下所示:

[HttpGet("{id}")]
[EnableQuery()]
public IActionResult GetAsset(int id)
{
    ... 
}