66

私は、新しいコントローラーごとに同じ基本コードを複製する必要がないように、汎用リポジトリーを使用して API コントローラーに基本的な CRUD メソッドを提供する基本コントローラーを用意するというアイデアをいじっています。しかし、ルーティング属性がベースコントローラーにあるときに認識されるという問題が発生しています。私が抱えている問題を正確に示すために、非常に単純な WebAPI コントローラーを作成しました。

メインコントローラーにGetメソッドがあり、それが直接から継承されてApiControllerいる場合、問題はなく、これは期待どおりに機能します。

[RoutePrefix("admin/test")]
public class TestController : ApiController
{
    [Route("{id:int:min(1)}")]
    public string Get(int id)
    {
        return "Success";
    }
}

Getメソッドをベース コントローラーに移動すると、404 ページの内容が返されます。

[RoutePrefix("admin/test")]
public class TestController : TestBaseController
{

}

public class TestBaseController : ApiController
{
    [Route("{id:int:min(1)}")]
    public string Get(int id)
    {
        return "Success";
    }
}

さらに興味深いメモ:

  • でアクションにアクセスできますGET /Test/1。そのため、まだデフォルトルートに基づいて検索しています。

  • にアクセスしようとするとPOST /admin/test、次の JSON が返されます

    { "Message":"リクエスト URI ' http://test.com/admin/test ' に一致する HTTP リソースが見つかりませんでした。", "MessageDetail":"'admin' という名前のコントローラーに一致するタイプが見つかりませんでした。 " }

ベースコントローラーからの属性でルーティングを機能させる方法を知っている人はいますか?

4

3 に答える 3

82

属性ルートは継承できません。これは意図的な設計上の決定でした。私たちは正しくないと感じ、それらを継承することが理にかなっている有効なシナリオを見ませんでした.

これをどこで使用するかについて、より現実的なシナリオを教えてください。

[更新(2014 年 3 月 24 日)]
MVC Web API の今後の 5.2 リリースではSystem.Web.Http.Routing.IDirectRouteProvider、ここで探している継承シナリオを有効にできる拡張ポイントが呼び出される予定です。最新のナイト ビルドを使用して、これを自分で試すことができます (ナイト ビルドの使用方法に関するドキュメントはこちら) 。

[更新(2014 年 7 月 31 日)]
Web API2.2リリースでこれを行う方法の例:

config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());

//---------

public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
    protected override IReadOnlyList<IDirectRouteFactory> 
    GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
    {
        // inherit route attributes decorated on base class controller's actions
        return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>
        (inherit: true);
    }
}
于 2013-11-14T22:03:11.833 に答える
28

Web API 2.2 を使用すると、次のことができます。

public class BaseController : ApiController
{
    [Route("{id:int}")]
    public string Get(int id)
    {
        return "Success:" + id;
    }
}
[RoutePrefix("api/values")]
public class ValuesController : BaseController
{
}

config.MapHttpAttributeRoutes(new CustomDirectRouteProvider());
public class CustomDirectRouteProvider : DefaultDirectRouteProvider
{
    protected override IReadOnlyList<IDirectRouteFactory> 
    GetActionRouteFactories(HttpActionDescriptor actionDescriptor)
    {
        return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>
        (inherit: true);
    }
}

ここで概説: http://www.asp.net/web-api/overview/releases/whats-new-in-aspnet-web-api-22

于 2014-07-26T10:00:48.683 に答える