.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
の検証メソッドが最初に呼び出され、次にメソッドon BuildingController
?が呼び出されます。campusId
のコントローラーレベルの検証を行う方法はありますか?編集:私が検証ロジックに言及するとき、私はAPIシグナルを意味します。 campusIdが有効か無効かを実際に決定するビジネスロジックではありません。
前もって感謝します!
ルートプレフィックスでプレースホルダーを使用する場合は、アクション自体にも含める必要があります。
[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との関係を確認するために使用できるサービス/リポジトリを用意することです。
campusId
と通信するときにユーザーにBuildingController
を提供し、BuildingController
を検証してcampusId
をDRY一種の方法です。
その場合は、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)
{...}
}
}