前回はレスポンスBodyのJsonに「snake_case」を適応しました。 今回はアクションメソッドの引数の変数名はそのままに、クエリパラメータを「snake_case」でリクエストして動作させるのがゴールです。
おさらい
名称 | 例 |
---|---|
Upper Camel Case (Pascal Case) | FirstName |
Lower Camel Case | firstName |
Snake Case | first_name |
Screaming Snake Case | FIRST_NAME |
Kebab Case | first-name |
Train Case | First-Name |
前提
こんなWeb APIがあったとします。
[ApiController] public class UsersController : ControllerBase { [HttpGet] public ActionResult<User[]> List([FromQuery]string firstName) { var users = new[] { new User { UserId = "001", FirstName = "Taro", LastName = "Yamada" }, new User { UserId = "002", FirstName = "Hanako", LastName = "Yamada" } }; return Ok(users.Where(u => firstName == null ? true : u.FirstName == firstName)); } }
この状態でのリクエストは「/api/users/?firstName=Taro」となります。
クエリパラメータに「snake_case」を適応する
当然、アクションメソッドの引数の変数名を「snake_case」に変えれば要件は満たされますが、全くもってスマートではありません。
// 変数名をsnake_caseに変える → 論外 [HttpGet] public ActionResult<User[]> List([FromQuery]string first_name)
ASP.NET MVCにはクライアントから送信されたリクエストをアクションメソッドの引数に対応させるモデルバインドという機構があります。 標準ではQueryStringValueProviderが実装されており、クエリパラメータの値をアクションメソッドの引数として渡してくれます。 今回はこのQueryStringValueProviderを拡張して「snake_case」に対応させます。 [参考]:ASP.NET Core でのカスタム モデル バインド
QueryStringValueProviderを継承したSnakeCaseQueryStringValueProviderと、MVCフレームワークへの登録に必要なIValueProviderFactoryを実装したSnakeCaseQueryStringValueProviderFactoryを用意します。 あとはStartupクラスのConfigureServicesメソッド内でValueProviderFactoriesに登録すれば「/api/users/?first_name=Taro」のリクエストでアクションメソッドの引数「firstName」に"Taro"の値が渡るようになります。
services.AddMvc(
options => options.ValueProviderFactories.Add(new SnakeCaseQueryStringValueProviderFactory()));
次回はSwaggerの対応です。