かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

ASP.NET WebAPIのOData v4でファンクション定義

Functionというのを定義してRPCみたいなこともODataでは出来ます。

まずは足し算。 ODataConventionModelBuilderのFunctionメソッドで関数の定義を作り、Returnsで戻り値を、Parameterでパラメータを指定します。

今回は足し算!

using System.Web.Http;
using System.Web.OData.Builder;
using System.Web.OData.Extensions; // MapODataServiceRouteに必要
using WebApplication5.Controllers;

namespace WebApplication5
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            var b = new ODataConventionModelBuilder();
            b.EntitySet<Person>("People");
            
            var addFunction = b.Function("Add");
            addFunction.Returns<double>();
            addFunction.Parameter<double>("x");
            addFunction.Parameter<double>("y");

            config.MapODataServiceRoute(
                "ODataRoute",
                "odata",
                b.GetEdmModel());

            
        }
    }
}

グローバルなFunctionは、コントローラにODataRoute属性をつけて定義します。こんな感じに。

[HttpGet]
[ODataRoute("Add(x={x},y={y})")]
public IHttpActionResult Add(double x, double y)
{
    return Ok(x + y);
}

すっきり。

注意点

おもむろにWeb.configのsystem.webServerの下に以下の行を追加します。こいつ追加しないとFunctionの呼び出しうまくいかないので注意。

<modules runAllManagedModulesForAllRequests="true" />

実行

T4テンプレートを再実行してテンプレートを生成します。するとContainerにAddメソッドが生えています。

var c = new Container(new Uri("http://localhost:7650/odata"));
Console.WriteLine(c.Add(10, 3).GetValue()); // 13

参考

複雑な型をパラメータに設定すると、以下のメッセージが表示されます。

危険な可能性のある Request.Path 値がクライアント (:) から検出されました。

これは、以下のページを参考に必要に応じて回避しましょう。