ASP.NET Web API で GET クエリ文字列パラメーターをモデル バインドする


ASP.NET MVC 4 と共に提供される ASP.NET Web API は、バックエンドで Entity Framework などと組み合わせつつ、軽量な HTTP サービスを構築するのに向いたフレームワークです。

※ Web API については下記などをご参照ください。

本日(7/10)時点では、ASP.NET MVC 4 の RC 版をお使いいただくことができますが、Beta 版から RC 版にかけて Web API の実装は比較的大きく修正がおこなわれています。今回は、その中のひとつ、モデルバインディングに関する変更点をご紹介します。


● モデル バインディング

ASP.NET MVC の特徴的な機能であるモデルバインダーを Web API でも利用できます。HTTP GET のリクエストとして URI よりパラメーターを受け取る場合、ルーティングで定義した URI のルート パラメーター、またはクエリ文字列パラメーターから取得でき、それらをコントローラーのアクション メソッドのパラメーターにバインドできます(モデル バインディング)。既定のモデル バインダーでも、プリミティブ型、複合型、コレクション、ディクショナリなどへ容易にバインド可能です。

例えば、下記のようなアクションメソッドで、パラメーター: int id を使用する場合を見てみましょう。

   1: public class HomeController : Controller
   2: {
   3:     public ActionResult ShowId(int id)
   4:     {
   5:         return Content(id.ToString());
   6:     }
   7: }

ルーティングは規定で下記のとおり id がルート パラメータに含まれています。

   1: routes.MapRoute(
   2:     name: "Default",
   3:     url: "{controller}/{action}/{id}",
   4:     defaults: new { controller = "Home",
   5:                     action = "Index",
   6:                     id = UrlParameter.Optional }
   7: );

これにより、下記のように URI に含めた “7” が ShowId の INT 型パラメーター id にバインドされます。

image

また、GET のクエリー文字列としてもパラメーターを付加することができます。

image


さらに、下記のようにモデル クラスを使って複合型をバインドすることもできます。

   1: public class ValueModel
   2: {
   3:     public string Value1 { get; set; }
   4:     public string Value2 { get; set; }
   5: }
   6:  
   7: public class HomeController : Controller
   8: {
   9:     public ActionResult ShowId(int id, ValueModel val)
  10:     {
  11:         return Content(val.Value1 + "-" + val.Value2);
  12:     }
  13: }

image

 

ここまでは、ASP.NET MVC フレームワークで提供される Controller クラスによる基本的なモデルバインドの動作です。

では、Web API ではどうでしょうか?



● Web API におけるモデル バインディング

上記と同じ処理を Web API でも試してみます。

   1: public class ValuesController : ApiController
   2: {
   3:     // GET api/values
   4:     public ValueModel Get(ValueModel val)
   5:     {
   6:         return val;
   7:     }
   8: }

Fidder を使って API を呼び出すと下記のようにエラー 500 となってしまいます。

image

image

これは、Web API のコントローラーのベースクラスが ApiController で、ASP.NET MVC の Controller とは実装が異なっていることによります。

この ApiController クラスでは HTTP リクエストをラップする Request オブジェクトが System.Net.Http.HttpRequestMessage クラスになり、これを通して受け取るパラメーターについては URI から取得するか、メッセージ Body から取得するかの指定が必要となっているためです。これを指定する属性としては、下記の2つが用意されています。

この属性を使って、先の Web API の実装コードを書き換えたのが下記となります。

   1: public class ValuesController : ApiController
   2: {
   3:     // GET api/values
   4:     public ValueModel Get([FromUri]ValueModel val)
   5:     {
   6:         return val;
   7:     }
   8:  
   9:     // GET api/values/5
  10:     public ValueModel Get(int id, [FromUri]ValueModel val)
  11:     {
  12:         return val;
  13:     }
  14:  
  15:     // POST api/values
  16:     public void Post([FromBody]ValueModel val)
  17:     {
  18:     }
  19:  
  20:     // PUT api/values/5
  21:     public void Put(int id, [FromBody]ValueModel val)
  22:     {
  23:     }
  24: }


この実行結果は下記のとおりです。GET のクエリー文字列として渡したパラメーターが ValueModel にバインドされ、正しく処理されていることがわかります。

image 


◆◆◆

以上のように、ASP.NET MVC の様々な機能を継承しつつ、より洗練されたフレームワークに仕上がってきている ASP.NET Web API は、MVC 4 とともにもう間もなく RTW となります。お楽しみに!

Comments (0)

Skip to main content