かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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 値がクライアント (:) から検出されました。

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