C#のGETメソッドに複数のパラメータを渡すことは、Web API開発において一般的な要件です。この記事では、ASP.NET Core内でこれを実現するための様々な手法を、明確性、保守性、ベストプラクティスに焦点を当てて解説します。
目次
従来のルーティングによるパラメータの受け渡し
従来のルーティングは、パラメータをURLパスに直接組み込みます。このアプローチは、リソースを直接識別する少数のパラメータに適しています。
例: IDとカテゴリIDに基づいて製品を取得する。
URL: /products/123/category/456
using Microsoft.AspNetCore.Mvc;
public class ProductsController : Controller
{
public IActionResult GetProduct(int productId, int categoryId)
{
// productIdとcategoryIdを処理する
return Ok($"Product ID: {productId}, Category ID: {categoryId}");
}
}
制限: パラメータの数が増えると、URLの可読性と保守性が低下します。オプションパラメータには柔軟性に欠けます。
属性ルーティングと[FromQuery]の使用
属性ルーティングは、URL構造に対するより高度な制御を提供します。[FromQuery]
を使用すると、パラメータはクエリ文字列から抽出されるため、多数のパラメータがあっても、URLはクリーンで管理しやすくなります。
例: 属性ルーティングと[FromQuery]
を使用した、同じ製品取得の例。
URL: /products?productId=123&categoryId=456
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
[HttpGet]
public IActionResult GetProduct([FromQuery] int productId, [FromQuery] int categoryId)
{
return Ok($"Product ID: {productId}, Category ID: {categoryId}");
}
}
このメソッドは、より良いURLの構成と可読性を促進します。[ApiController]
属性により、自動的なモデル検証とレスポンス処理が可能になります。
オプションパラメータの処理
オプションパラメータは柔軟性を高めます。コントローラアクションのシグネチャ内でデフォルト値を使用します。
[HttpGet]
public IActionResult GetProduct([FromQuery] int productId, [FromQuery] int categoryId, [FromQuery] int pageSize = 10)
{
return Ok($"Product ID: {productId}, Category ID: {categoryId}, Page Size: {pageSize}");
}
ここで、pageSize
は、クエリ文字列で指定されていない場合、10にデフォルト設定されます。
モデルバインディングの活用
複数のパラメータの場合は、専用のモデルを作成することを検討してください。これにより、コードの構成と保守性が向上します。ASP.NET Coreは、クエリ文字列をモデルのプロパティに自動的にバインドします。
public class ProductFilter
{
public int ProductId { get; set; }
public int CategoryId { get; set; }
public int PageSize { get; set; } = 10;
}
[HttpGet]
public IActionResult GetProduct(ProductFilter filter)
{
return Ok($"Product ID: {filter.ProductId}, Category ID: {filter.CategoryId}, Page Size: {filter.PageSize}");
}
堅牢なエラー処理
必要なパラメータの欠落やデータ型の無効など、潜在的なエラーは常に処理する必要があります。モデル検証や明示的なパラメータチェックなどの手法を使用して、これらの状況を適切に処理します。
[HttpGet]
public IActionResult GetProduct(ProductFilter filter)
{
if (filter.ProductId == 0)
{
return BadRequest("Product ID is required.");
}
// ... 他のロジック ...
}