【问题标题】:.NET Core 3 Web API Multiple Routes detected build error.NET Core 3 Web API Multiple Routes 检测到构建错误
【发布时间】:2020-12-14 16:23:50
【问题描述】:

我有两个主控制器(还有第三个,auth,但这不会导致路由错误)。一个是在父级操作,另一个是在子级操作的api控制器。我不会粘贴所有控制器代码,因为它不是必需的,只是路由。

父级有 3 条基本路线。一个获取对象列表,一个获取单个对象,一个创建新记录:

[Route("api/npos")]
[ApiController]

// GET NPO LIST
[HttpGet()]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetNPOs([FromQuery] PagingParams paging) // code

// GET NPO BY ID
[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetNPOById(int id) // code

[Route("CreateNPO")]
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> CreateNPO([FromBody] NPOtoCreateDto createDto) // code here

子路由是操作npos中的用户列表,本身有几条路由。

[Route("api/npos/{npoId}/users")]
[ApiController]

// GET USER LIST FOR NPO
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetUsersForNPO(int npoId) // code

[HttpPost]
public async Task<IActionResult> AddUserToNPO(int npoId, string userId) // code

[HttpDelete]
public async Task<IActionResult> RemoveUserFromNPO(int npoId, string userId) // code

当我通过 IIS Express 运行项目时,Startup CS 中的UseEndpoints 方法抛出:

System.ArgumentException: 'The route parameter name 'npoId' appears more than one time in the route template. (Parameter 'routeTemplate')' 

有什么帮助吗?我认为我的路线配置相当可靠。

【问题讨论】:

  • 您好!对不起。我还没有机会测试它,但我会的。
  • 嗨@J.G.Sable,你有更新吗?

标签: .net api asp.net-core asp.net-apicontroller


【解决方案1】:

这是一个工作演示:

控制器:

[Route("api/npos")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET NPO LIST
    [HttpGet()]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetNPOs([FromQuery] PagingParams paging) // code

    // GET NPO BY ID
    [HttpGet("{id}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetNPOById(int id) // code

    [Route("CreateNPO")]
    [HttpPost]
    [ProducesResponseType(StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> CreateNPO([FromBody] NPOtoCreateDto createDto) // code here
}


[Route("api/npos/{npoId}/users")]
[ApiController]
public class ChildController: ControllerBase
{
    // GET USER LIST FOR NPO
    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetUsersForNPO(int npoId) // code

    [HttpPost]
    public async Task<IActionResult> AddUserToNPO(int npoId, string userId) // code

    [HttpDelete]
    public async Task<IActionResult> RemoveUserFromNPO(int npoId, string userId) // code
}

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();          
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

顺便说一句,如果两个控制器包含如下继承关系:

[Route("api/npos")]
[ApiController]
public class ValuesController : ControllerBase
{}

[Route("api/npos/{npoId}/users")]
[ApiController]
public class ChildController: ValuesController
{}

你需要改变GetUsersForNPO路由,因为当ChildController扩展ValuesController时,ChildController拥有ValuesController拥有的动作。GetNPOsGetUsersForNPO动作会冲突。虽然参数是从不同的来源绑定的。GetNPOs get parameter from query 和 GetUsersForNPO get from route, 但无论路由和查询,它们都是可选的。所以这使得请求匹配多个端点。作为一种解决方法,只需更改 GetUsersForNPO 路由如下:

[Route("GetUsersForNPO")]
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetUsersForNPO(int npoId) 

【讨论】:

    猜你喜欢
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2018-02-21
    • 2017-08-05
    • 1970-01-01
    • 2018-11-17
    相关资源
    最近更新 更多