2017-08-01 36 views
5

在.NET Core MVC中使用嵌套路線尋找最佳實踐。NETCORE 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中的每個操作方法中都必須有一個比驗證邏輯更好的方法。

  • 有沒有辦法在不同的控制器上級聯多個Action方法?因此,CampusController上的驗證方法將首先被調用,然後調用BuildingController上的方法?
  • 有沒有辦法讓控制器級別的驗證campusId可能會短路並在驗證失敗時返回ActionResult?

編輯:當我指的驗證邏輯我的意思是API信號;而不是實際確定campusId是否有效的業務邏輯。

在此先感謝!

回答

5

如果路由前綴使用佔位符,你也需要把它列入行動本身

[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

這個解決方案對我來說最重要,因爲整個'campus'模型不需要在'BuildingController'類中;而只需要執行一個簡單的驗證檢查。謝謝! –

+0

爲什麼不使用FromRoute而不是FromQuery? – 000

+0

@Sam'FromRoute'是正確的。我剛從OP複製了參數。這是我的一個疏忽。將更新。謝謝你指出。 – Nkosi

2

這聽起來像你希望你的用戶提供一個campusId聊到BuildingController的時候,你的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) 
     {...} 
    } 
}