miso_soup3 Blog

主に ASP.NET 関連について書いています。

ASP.NET Web API クエリの文字列の配列を取得

/one?value=1&value=2&value=3

のような URL でリクエストがきた場合に、クエリ文字列の同じキーの値を配列として取得する方法。

ASP.NET Web API にて
  • ApiController の Request プロパティからクエリ文字列を取得する
  • アクションメソッドの引数にバインドさせる

の2つの方法がある。

using System.Linq;
using System.Net.Http;
using System.Web.Http;

namespace QueryArray.Controllers
{
    public class MyController : ApiController
    {
        //one?value=1&value=a
        //return:"1,a"
        [HttpGet]
        [Route("one")]
        public string Get()
        {
            string[] value = GetQueryString("value");
            return value == null ? 
                string.Empty : string.Join(",", value);
        }

        //two?value=1&value=a
        //return:"1,a"
        [HttpGet]
        [Route("two")]
        public string Get([FromUri] int[] value)
        {
            return value == null ?
                string.Empty : string.Join(",", value);
        }


        //three?value=1&value=a
        //return:"1,a"
        [HttpGet]
        [Route("three")]
        public string Get([FromUri]MyModel model)
        {
            if (model == null || model.Value == null)
                return string.Empty;
            return string.Join(",", model.Value);
        }

        /// <summary>
        /// 指定したキーのクエリ文字列の値を取得します
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private string[] GetQueryString(string key)
        {
            return Request.GetQueryNameValuePairs()
                .Where(e => e.Key == key)
                .Select(e => e.Value)
                .ToArray();
        }
    }

    public class MyModel
    {
        public int[] Value { get; set; }
    }
}
ASP.NET MVC では

ASP.NET MVC の場合も似た感じ。
ただ、Request.QueryString["value"] でカンマ区切りで返ってくるので、以下の通りとなる。

using System.Web.Mvc;

namespace QueryArray.Controllers
{
    public class HomeController : Controller
    {
        //Home/Array?value=1&value=a
        public ActionResult Array()
        {
            string[] value = Request.QueryString["value"]?.Split(',');
            ViewBag.Message = value;
            return View();
        }

        //Home/Array2?value=1&value=a
        public ActionResult Array2(string[] value)
        {
            ViewBag.Message = value;
            return View();
        }
    }
}
違い

ASP.NET Web API の ApiController:

public abstract class ApiController : IHttpController, IDisposable
{
  //....
  public System.Net.Http.HttpRequestMessage Request { get; set; }
}

ASP.NET MVC の Controller:

public abstract class Controller : ControllerBase ...
{
  //....
  public System.Web.HttpRequestBase Request { get; }
}

HttpRequestBase は abstract。

ASP.NET Web API の方が、Request の差し替えができ単体テストもしやすい。