.NET Core 3 Web API 多个路由检测到构建错误

问题描述 投票:0回答:1

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

家长级别有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')' 

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

.net asp.net-core asp.net-core-webapi asp.net-apicontroller
1个回答
0
投票

这是一个工作演示:

控制器:

[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
}

启动.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 所具有的操作。
GetNPOs
GetUsersForNPO
操作会冲突。虽然参数是从不同的源绑定的。
GetNPOs
获取参数from query 和
GetUsersForNPO
从路由获取,但是无论路由和查询,它们都是可选的。因此这使得请求匹配多个端点。作为解决方法,只需更改
GetUsersForNPO
路由,如下所示:

[Route("GetUsersForNPO")]
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetUsersForNPO(int npoId) 
© www.soinside.com 2019 - 2024. All rights reserved.