NET CORE MVC - 如何使用嵌套的多参数路由
Posted
技术标签:
【中文标题】NET CORE MVC - 如何使用嵌套的多参数路由【英文标题】:NETCORE MVC - How to work with nested, multi-parameterized routes 【发布时间】:2017-08-01 22:10:41 【问题描述】:寻找在 .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
并返回一个 4xx 编码的 IActionResult(如果它无效)。必须有比在BuildingController
内的每个操作方法中包含验证逻辑更好的方法。
CampusController
上的验证方法会先被调用,然后再调用BuildingController
上的方法?
有没有办法对campusId
进行控制器级别的验证,如果验证失败,它可能会短路并返回 ActionResult?
编辑:当我提到验证逻辑时,我指的是 API 信号;不是实际确定 CampusId 是否有效的业务逻辑。
提前致谢!
【问题讨论】:
您还可以为整个控制器类创建一个自定义过滤器属性,如[Authorize]
,以通过使用数据库、路由值、查询参数、登录用户等来验证每个 HTTP 请求。
【参考方案1】:
如果在路由前缀中使用占位符,您还需要将其包含在操作本身中
[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 的关系(如果需要)。
【讨论】:
这个解决方案对我来说最有意义,因为整个campus
模型不需要在 BuildingController
类中;而只是需要执行一个简单的验证检查。谢谢!
为什么不使用 FromRoute 而不是 FromQuery?
@Sam FromRoute
是正确的。我刚刚从 OP 复制了参数。这是我的疏忽。会更新。感谢您指出这一点。【参考方案2】:
听起来您希望您的用户在与BuildingController
交谈时提供campusId
,并且您的BuildingController
以一种干燥的方式验证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 - 如何使用嵌套的多参数路由的主要内容,如果未能解决你的问题,请参考以下文章
如何将多个参数传递给 ASP.NET CORE MVC 中的 HttpGet 方法?
在 ASP.NET Core MVC 中将自定义查询参数添加到操作 URL
如何将两个数组作为 POST 请求参数从 AJAX 发送到 MVC 控制器(ASP .NET Core 3.1 剃须刀)?