NET CORE MVC - 如何使用嵌套的多参数化路由
NETCORE MVC - How to work with nested, multi-parameterized routes
寻找在 .NET Core MVC 中使用嵌套路由的最佳实践。
假设 CampusController.cs
使用基本模型:
[Route("api/campus/")]
public class CampusController : Controller
{
...
[HttpGet]
[Route("{campusId}")]
public IActionResult GetCampusInfo ([FromQuery]int campusId) { ... }
}
并且BuildingController.cs
与子模型一起工作:
[Route("api/campus/{campusId}/building")]
public class BuildingController : Controller
{
...
[HttpGet]
[Route("{buildingId}")]
public IActionResult GetBuilding ([FromQuery]int buildingId) { ... }
[Route("{buildingId}/")]
public IActionResult GetBuilding ([FromQuery]int buildingId) { ... }
....
(more Action Methods)
}
如果 buildingId
直接映射到数据库,即使提供的 campusId
不是父数据库,它也可以检索。为了在调用 /api/campus/{campusId}/building/{buildingId}
时保持 URL 干净,我想验证 {campusId}
和 return 一个 4xx 编码的 IActionResult(如果它无效)。必须有比在 BuildingController
.
中的每个操作方法中包含验证逻辑更好的方法
- 有没有办法在不同的控制器上级联多个Action方法?因此,首先会调用
CampusController
上的验证方法,然后调用 BuildingController
? 上的方法
- 有没有办法对
campusId
进行控制器级别的验证,如果验证失败,return 可能会短路,并且 return ActionResult?
编辑:当我提到验证逻辑时,我指的是 API 信号;不是实际确定 campusId is/isn 是否有效的业务逻辑。
提前致谢!
如果在路由前缀中使用占位符,您还需要将其包含在操作本身中
[Route("api/campus/{campusId:int}/building")]
public class BuildingController : Controller {
//...
[HttpGet]
[Route("{buildingId:int}")] // Matches GET api/campus/123/building/456
public IActionResult GetBuilding ([FromRoute]int campusId, [FromRoute]int buildingId) {
//... validate campus id along with building id
}
}
如果担心验证的重复代码,请为校园相关请求创建一个基本控制器并使用共享验证方法。
另一种选择是 service/repository 可用于验证校园 ID 及其与所提供建筑物 ID 的关系(如果需要)。
听起来您希望您的用户在与 BuildingController
交谈时提供 campusId
,而您的 BuildingController
以一种 DRY 方式验证 campusId
.
如果是这种情况,您可以为 BuildingController
方法创建一个输入模型:
public class BuildingIdInput
{
[Required]
public int? CampusId { get; set; }
[Required]
public int? BuildingId { get; set; }
}
然后你可以让 MVC 将用户输入绑定到这个模型。
[Route("api/campus")]
public class BuildingController : Controller
{
[HttpGet]
[Route("{campusId}/building/{buildingId}")]
public IActionResult GetBuilding (BuildingIdInput input)
{
if (ModelState.IsValid)
{...}
}
}
寻找在 .NET Core MVC 中使用嵌套路由的最佳实践。
假设 CampusController.cs
使用基本模型:
[Route("api/campus/")]
public class CampusController : Controller
{
...
[HttpGet]
[Route("{campusId}")]
public IActionResult GetCampusInfo ([FromQuery]int campusId) { ... }
}
并且BuildingController.cs
与子模型一起工作:
[Route("api/campus/{campusId}/building")]
public class BuildingController : Controller
{
...
[HttpGet]
[Route("{buildingId}")]
public IActionResult GetBuilding ([FromQuery]int buildingId) { ... }
[Route("{buildingId}/")]
public IActionResult GetBuilding ([FromQuery]int buildingId) { ... }
....
(more Action Methods)
}
如果 buildingId
直接映射到数据库,即使提供的 campusId
不是父数据库,它也可以检索。为了在调用 /api/campus/{campusId}/building/{buildingId}
时保持 URL 干净,我想验证 {campusId}
和 return 一个 4xx 编码的 IActionResult(如果它无效)。必须有比在 BuildingController
.
- 有没有办法在不同的控制器上级联多个Action方法?因此,首先会调用
CampusController
上的验证方法,然后调用BuildingController
? 上的方法
- 有没有办法对
campusId
进行控制器级别的验证,如果验证失败,return 可能会短路,并且 return ActionResult?
编辑:当我提到验证逻辑时,我指的是 API 信号;不是实际确定 campusId is/isn 是否有效的业务逻辑。
提前致谢!
如果在路由前缀中使用占位符,您还需要将其包含在操作本身中
[Route("api/campus/{campusId:int}/building")]
public class BuildingController : Controller {
//...
[HttpGet]
[Route("{buildingId:int}")] // Matches GET api/campus/123/building/456
public IActionResult GetBuilding ([FromRoute]int campusId, [FromRoute]int buildingId) {
//... validate campus id along with building id
}
}
如果担心验证的重复代码,请为校园相关请求创建一个基本控制器并使用共享验证方法。
另一种选择是 service/repository 可用于验证校园 ID 及其与所提供建筑物 ID 的关系(如果需要)。
听起来您希望您的用户在与 BuildingController
交谈时提供 campusId
,而您的 BuildingController
以一种 DRY 方式验证 campusId
.
如果是这种情况,您可以为 BuildingController
方法创建一个输入模型:
public class BuildingIdInput
{
[Required]
public int? CampusId { get; set; }
[Required]
public int? BuildingId { get; set; }
}
然后你可以让 MVC 将用户输入绑定到这个模型。
[Route("api/campus")]
public class BuildingController : Controller
{
[HttpGet]
[Route("{campusId}/building/{buildingId}")]
public IActionResult GetBuilding (BuildingIdInput input)
{
if (ModelState.IsValid)
{...}
}
}