WebAPIでコンテンツネゴシエーションを操作する方法

ASP.Net Web APIは、ステートレスでRESTfulなHTTPサービスを構築するために使用される軽量のフレームワークです。RESTfulサービスは、リソースの概念に基づいた、軽量でステートレスなクライアントサーバーベースのキャッシュ可能なサービスです。RESTはアーキテクチャスタイルであり、ステートレスサービスを実装するために使用される一連の制約です。これは、再利用可能でスケーラブルなサービスを作成するために使用されるアーキテクチャパラダイムです。

さまざまなタイプのデバイスからサービスを利用したい場合が多いため、要求された形式でのリソースの表現は興味深いトピックです。コンテンツネゴシエーションは、WebAPIの最も重要な概念の1つです。比較的単純な概念ですが、このトピックには多くの誤解や誤解があります。Web APIを使用してRESTfulサービスを設計および実装する場合、多くの場合、コンテンツネゴシエーションに対処する必要があります。

交渉されたコンテンツとは何ですか?なぜそれが重要なのですか?

コンテンツネゴシエーションは、着信HTTP要求の構造を検査して、同じリソースの複数の使用可能な表現の中からリソースの最適な表現を決定するプロセスとして定義できます。本質的に、コンテンツネゴシエーションは、同じURLがさまざまな形式で同じコンテンツを提供できるようにする概念です。コンテンツネゴシエーションを利用して、優先するメディアタイプを選択できます。

Web APIでは、コンテンツネゴシエーションはランタイム(サーバー側)によって実行され、クライアント側からの着信要求に対する応答を返すために使用されるメディアタイプフォーマッターを決定します。

コンテンツネゴシエーションは、メディアタイプとメディアタイプフォーマッターを中心にしています。前者はHTTP要求とHTTP応答の「content-type」ヘッダーの値を参照しますが、後者は.NETタイプを対応するHTTPデータに変換するために使用されます。Web APIのメディアタイプフォーマッターは、MediaTypeFormatterと呼ばれる抽象クラスで表されることに注意してください。

Web APIフレームワークには、デフォルトで次のフォーマッターが付属しています。

  • System.Net.Http.Formatting.JsonMediaTypeFormatter
  • System.Net.Http.Formatting.XmlMediaTypeFormatter
  • System.Net.Http.Formatting.FormUrlEncodedMediaTypeFormatter
  • System.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter

Web APIでコンテンツネゴシエーションをカスタマイズするために利用する必要がある主な拡張ポイントは、メディアタイプのマッピングです。Web APIは、デフォルトで次のメディアタイプマッピングを提供することに注意してください。

  • QueryStringMapping
  • UriPathExtensionMapping
  • RequestHeaderMapping
  • MediaRangeMapping

カスタムメディアタイプマッピングを構築するには、以下のコードスニペットに示すように、MediaTypeMappingを拡張するクラスを作成する必要があります。

public class MediaTypeMapping : MediaTypeMapping

{

   protected override double OnTryMatchMediaType(HttpResponseMessage response)

     {

                //Write your custom code here

     }

}

次のコードスニペットは、HttpConfiguration.Formattersコレクションを反復処理することにより、WebAPIでサポートされているすべてのフォーマッターの名前を取得する方法を示しています。

   [HttpGet]

       public List GetAllFormatters()

       {

           List lstFormaters = new List();

           foreach (var formatter in this.Configuration.Formatters)

           {

               lstFormaters.Add(formatter.GetType().Name);

           }

           return lstFormaters;

       }

次に、コンテンツネゴシエーションを使用して、必要なフォーマッターを選択し、必要な形式でコンテンツを取得する方法を見ていきましょう。次のエンティティクラスについて考えてみます。

public class CustomerDTO

   {

       public Int32 Id

       { get; set; }

       public string FirstName

       { get; set; }

       public string LastName

       { get; set; }

       public string Address

      { get; set; }

   }

次に、CustomerDTOタイプのリストにデータを入力して返すメソッドがあるとします。

private List GetCustomerData()

       {

           List lstCustomers = new List();

           CustomerDTO customer = new CustomerDTO();

           customer.Id = 1;

           customer.FirstName = "Joydip";

           customer.LastName = "Kanjilal";

           customer.Address = "Hyderabad, India";

           lstCustomers.Add(customer);

           return lstCustomers;

       }

次のWebAPIメソッドは、使用可能なデフォルトのコンテンツネゴシエーションメカニズムに基づいて、WebAPIメソッドからの応答としてHttpResponseMessageを返す方法を示しています。

[HttpGet]

       public HttpResponseMessage GetCustomers()

       {

           List lstCustomers = GetCustomerData();

           IContentNegotiator negotiator = Configuration.Services.GetContentNegotiator();

           ContentNegotiationResult result = negotiator.Negotiate(typeof(CustomerDTO), Request, Configuration.Formatters);

           return new HttpResponseMessage()

           {

               Content = new ObjectContent (lstCustomers, result.Formatter, result.MediaType.MediaType)

         };

       }

フォーマッターコレクションで利用可能な特定のフォーマッターを使用する場合は、以下のコードスニペットに示されているのと同じメソッドを書き直すことをお勧めします。

[HttpGet]

       public HttpResponseMessage GetCustomers()

       {

           List lstCustomers = GetCustomerData();

           return new HttpResponseMessage()

           {

               Content = new ObjectContent (lstCustomers, Configuration.Formatters[1])

           };

      }

OK; では、どのようにして独自のカスタムフォーマッタを構築しますか?カスタムメディアタイプフォーマッターを作成するには、MediaTypeFormatter抽象クラスを拡張するクラスを作成する必要があります。次に、作成したクラス内にカスタムコードを記述して、MediaTypeFormatter抽象基本クラスのメソッドをオーバーライドする必要があります。

public class CustomMediaTypeFormatter : MediaTypeFormatter

   {

       public override bool CanReadType(Type type)

       {

           throw new NotImplementedException();

       }

       public override bool CanWriteType(Type type)

       {

           throw new NotImplementedException();

       }

   }

カスタムフォーマッターを配置したら、それをフォーマッターコレクションに簡単に追加できます。

config.Formatters.Add(new CustomMediaTypeFormatter ());