在.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}
时保持网址清洁,我想验证{campusId}
并返回4xx编码的IActionResult,如果它无效的话。必须有一种比在BuildingController
内的每个操作方法中包含验证逻辑更好的方法。
CampusController
上的验证方法,然后在BuildingController
上调用方法?campusId
的控制器级验证可以短路并返回ActionResult?编辑:当我提到验证逻辑时,我指的是API信号;而不是实际确定campusId是否有效的业务逻辑。
提前致谢!
答案 0 :(得分:11)
如果在路由前缀中使用占位符,则还需要将其包含在操作本身
中[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
}
}
如果担心重复验证代码,请为校园相关请求创建一个基本控制器,并使用共享验证方法。
另一个选择是拥有一个服务/存储库,可用于验证校园ID及其与所提供的建筑物ID的关系(如果需要)。
答案 1 :(得分:3)
听起来您希望您的用户在与campusId
交谈时提供BuildingController
,并希望您的BuildingController
以干燥的方式提供campusId
。< / p>
如果是这种情况,您可以为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)
{...}
}
}