miso_soup3 Blog

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

ASP.NET Web API OData で enum はどのように表現されるか

ASP.NET Web API OData で、enum の値や定義はどのように表現されるか確認しました。
結果は、出力の方はもちろんどちらも可能で、enum の定義(とある enum はどのような列挙子をもつか)は、v4 では対応しているようでした。

Getting started with ASP.NET Web API 2.2 for OData v4.0 この記事に v4 から enum サポートしたよーと書いてあります。

Support for enums

We already had support for enums in Web API OData v3.0 by serializing them as strings, but the new version of the protocol has added full support for them, so we have upgraded our enum support accordingly. In order to use enums you just need to define a property with an enum type and we’ll represent it as an enum in the $metadata and the clients will able to use enum query operators in $filter clauses. There are
also specific overloads on the model builder in case we want to configure the enumeration explicitly.

以下は試したときの手順です。

OData エンドポイントを用意して試してみる

まずは、以下のようなクラスと enum を用意します。Product の ColorType プロパティを enum で定義しました。

namespace ODataenumSample.Models
{
    public enum ColorType
    {
        Red = 0,
        Blue = 1,
        Green = 2,
    }

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }

        public ColorType ColorType { get; set; }
    }
}

このモデルを使い、v3 と v4 の両方で OData のエンドポイントを ASP.NET Web API Odata を使って用意します。
手順は以下のサイトのチュートリアルを参照しました。サンプルデータを Code First で用意します。

v4 : Create an OData v4 Endpoint Using ASP.NET Web API 2.2
v3 : Creating an OData v3 Endpoint with Web API 2
Code First を使った初期データの用意:Use Code First Migrations to Seed the Database

v3 と v4 で微妙にコードが違うので注意が必要です。

補足情報:

・ASP.NET Web API は 2.2 から、OData v4 に対応しました。
・Visual Studio 2015 Update 1 では、v4 OData スキャフォールディングが用意されておりません。なので、拡張機能 OData v4 Web API Scaffolding を使いました。
・もしエラーが起きた場合はこちらの記事が参考になるかもしれません。

v4 の方では、下のように WebApiConfig.cs を記述します。v3 の方もメソッド名等が違うだけでほとんど変わりません。

ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");

config.MapODataServiceRoute(
  routeName: "ODataRoute",
  routePrefix: "odata",
  model: builder.GetEdmModel());
$metadata

用意した OData の $metadata を確認したものが下の画像です。上が v4 で下が v3。v4 の方には enum ColorType の列挙子があることがわかります。

f:id:miso_soup3:20160106193125p:plain

v3 で enum の定義を $metadata に含めることはできるのか?

Tutorial & Sample Use enumeration types in OData

こちらの記事を見るとできそうだったのですが、EdmModel を自分で作り上げる必要があり面倒?そうだったので、確認はしておりません。

クライアントでは

v4 の方に enum の定義があることを確認できたので、クライアントコードを自動生成したら enum も作ってくれるのではーと思い試してみました。

OData v4 のクライアントコード生成は、こちらの記事を参照します。
WEB API ODATA V4 USING AN ODATA T4 GENERATED CLIENT PART 8

記事にある通り、「OData v4 Client Code Generator」の拡張機能をインストールし、「OData Client」の .tt ファイルを追加します。次に、nuget で「Micorosft.OData.Client」をインストール。
先ほど用意した OData v4 エンドポイントのプロジェクトの方を立ち上げておき、MetadataDocumentUri に URL を入力し、.tt ファイルを実行しコードを生成します。

自動生成されたコードをのぞいてみると…enum がありました。

f:id:miso_soup3:20160106194209p:plain

↓のようにクライアント側のコードを書いて、OData でデータを取得できます。

class Program
{
    static void Main(string[] args)
    {
        var context = new Container(new Uri("http://localhost:16334/odata/"));
            
        foreach(var product in context.Products)
        {
            if (product.ColorType == ODataenumSample.Models.ColorType.Red)
            {
                Console.WriteLine("Redです");
            }
            Console.WriteLine($"{product.Name} {product.Category} {product.ColorType}");
        }

    }
}

f:id:miso_soup3:20160106194259p:plain