かずきのBlog@hatena

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

ASP.NET Odata v4.0でアクション定義

ファンクションの次はアクション。こいつも、ファンクションと同じで、全体、エンテティ、エンテティのコレクションの3つに定義できます。Add, Add2, Add3という名前で定義を以下のようにやります。

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 addAction = b.Action("Add");
            addAction.Returns<double>();
            addAction.Parameter<double>("x");
            addAction.Parameter<double>("y");

            var addTypeAction = b.EntityType<Person>().Action("Add2");
            addTypeAction.Returns<double>();
            addTypeAction.Parameter<double>("x");
            addTypeAction.Parameter<double>("y");

            var addCollectionAction = b.EntityType<Person>().Collection
                .Action("Add3");
            addCollectionAction.Returns<double>();
            addCollectionAction.Parameter<double>("x");
            addCollectionAction.Parameter<double>("y");

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

そして、コントローラにメソッドを定義します。ActionはHttpPostで定義します。

[HttpPost]
[ODataRoute("Add")]
public IHttpActionResult Add(ODataActionParameters p)
{
    return Ok((double)p["x"] + (double)p["y"]);
}

[HttpPost]
public IHttpActionResult Add2(int key, ODataActionParameters p)
{
    return Ok((double)p["x"] + (double)p["y"]);
}

[HttpPost]
public IHttpActionResult Add3(ODataActionParameters p)
{
    return Ok((double)p["x"] + (double)p["y"]);
}

引数がODataActionParametersとまぁいけてない感じですね…。

T4テンプレートが生成してくれるクライアントからは以下のような感じで呼び出せます。

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

// Add2
var answer2 = c.People.ByKey(new Dictionary<string, object>
    {
        { "Id", 33 }
    })
    .Add2(10, 3)
    .GetValue();
Console.WriteLine(answer2);

// Add3
var answer3 = c.People.Add3(10, 3).GetValue();
Console.WriteLine(answer3);

Actionは、Postで送られる関係か、引数や戻り値に複雑な型を渡しても平気な点がいいかもですね。