我有两个主控制器(还有第三个,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')'
有什么帮助吗?我认为我的路线配置相当可靠。
这是一个工作演示:
控制器:
[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)