normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

ASP.NET MVC4 の Web API を学んでみる その4 〜Filter編〜

その1 〜 その3 にて、 Web API の動作について解説したため、今回は Web API で Filter を利用する方法について紹介する。

コントローラ と Web API 用コントローラの違い

まず重要な点として、「通常のコントローラに適用する Filter と Web API のコントローラに適用する Filter では、継承するクラスが異なる」という点が存在する。

  • コントローラに適用する Filter → System.Web.Mvc.FilterAttribute
  • Web API のコントローラに適用する Filter → System.Web.Http.Filters.IFilter

コントローラに適用する Filter については別途「 ASP.NET MVCにおけるFilterの作成方法と実行順序制御 id:waritohutsu:20090704 」を参照いただくとして、Web API のコントロールに適用する Filter の作成を紹介する。
また、どうやらコントローラ向けのフィルタには存在したフィルタの実行順序制御プロパティである Order は存在しないようだ。

Web API 向け コントローラに適用する Filter を作成する

Web API 向けに作成されたフィルター・インターフェースである System.Web.Http.Filters.IFilter を継承した System.Web.Http.Filters.ActionFilterAttribute 属性クラスを利用し、以下の属性クラスを作成する。

  • MyActionFilterAttribute.cs
using System.Diagnostics;
using System.Web.Http.Filters;

namespace Mvc4WebApiApp.Filters
{
    public class MyActionFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
    {
        private readonly string message;

        public MyActionFilterAttribute(string message = "デフォルト")
        {
            this.message = message;
        }

        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            Debug.WriteLine("★★OnActionExecuted =" + message);
            base.OnActionExecuted(actionExecutedContext);
        }

        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            Debug.WriteLine("★★OnActionExecuting =" + message);
            base.OnActionExecuting(actionContext);
        }
    }
}

継承元の ActionFilterAttribute 属性クラスはクラスとメソッドのみに付与可能な属性でり、多重に付与が可能であるため、こちらが引き継がれる。

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IFilter
    {
        //(以下略)

Web API 向け Filter を利用し、ApiControllerに適用する

Filter を作成したので、次に Web API 向けコントローラである ApiController に対して同 Filter を適用する。適用を検証するため、以下の ApiController を作成した。

using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Diagnostics;
using System.Reflection;
using Mvc4WebApiApp.Filters;

namespace Mvc4WebApiApp.Controllers
{
    [MyActionFilter("①クラス単位")]
    public class ValuesController : ApiController
    {
        // GET /api/values
        [MyActionFilter("②メソッド単位")]
        public string[] Get()
        {
            Debug.WriteLine("☆☆ 現在のメソッド = {0}.{1}()",
                new object[] { this.GetType().Name, MethodBase.GetCurrentMethod().Name });
            return Enumerable.Range(1, 10).Select(n => "value No." + n).ToArray();
        }
        
        //(中略)

Web API 向け Filter の動作確認

作成した Web API 向けフィルターとコントローラを利用したアプリケーションの動作を確認する。Visual Studio からアプリケーションを起動し、http://loaclhost:<ポート番号>/api/values にアクセスすると、以下が「出力」ウィンドウに表示されることが確認できる。

★★OnActionExecuting =①クラス単位
★★OnActionExecuting =②メソッド単位
☆☆ 現在のメソッド = ValuesController.Get()
★★OnActionExecuted =②メソッド単位
★★OnActionExecuted =①クラス単位