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

时间:2019-06-06 08:38:32

标签: c# .net-core odata asp.net-core-webapi

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

呼叫 https://localhost:xxx/api/Assets https://localhost:xxx/api/Assets/1

返回所有资产,而后者应仅返回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());
            });

        }

这没什么区别。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

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

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

根据OData v4 Web API docs

  

以下是方法签名的一些规则:

     
      
  • 如果路径包含键,则操作应具有名为key的参数。
  •   
  • 如果路径包含导航属性中的键,则该操作应具有一个名为relatedKey的参数。
  •   
  • POST和PUT请求采用实体类型的参数。
  •   
  • PATCH请求采用类型为Delta的参数,其中T为实体类型。
  •   

我们应该有一个名为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)
{
    ....
}

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

根据OData v4 Web API docs

  

当Web API获得OData请求时,它将请求映射到控制器名称和操作名称。映射基于HTTP方法和URI。例如,GET / odata / Products(1)映射到ProductsController.GetProduct。

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

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

答案 1 :(得分:0)

这对我有用...

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


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