ASP.NET Web APIのルーティングのカスタマイズ

WebApiコントローラの名前に「Api」という接尾辞が付いています(例:StudentsApiController、InstructorsApiControllerの場合)。 MVCコントローラとWebApiコントローラを簡単に区別するためにこれを行います。 WebApiのルートを

http://localhost:50009/api/students/5 and not http://localhost:50009/api/studentsapi/5.

現在、これを達成するために、私は

routes.MapHttpRoute(
name: "GetStudents",
routeTemplate: "api/students/{id}",
defaults: new { controller = "StudentsApi", id = RouteParameter.Optional });

routes.MapHttpRoute(
name: "GetInstructors",
routeTemplate: "api/instructors/{id}",
defaults: new { controller = "InstructorsApi", id = RouteParameter.Optional });

私のコントローラに各メソッドのルートを追加する必要があるので、これは非常に面倒です。私はルートを処理している間に自動的に "api"接尾辞をコントローラ名に追加するルートテンプレートを設定する簡単な方法が必要であると考えています。

12

4 答え

@ Youssef Moussaouiの指示に従い、私はこの問題を解決した次のコードを書いた。

public class ApiControllerSelector : DefaultHttpControllerSelector
{
    public ApiControllerSelector(HttpConfiguration configuration)
        : base(configuration)
    {
    }

    public override string GetControllerName(HttpRequestMessage request)
    {
        if (request == null)
            throw new ArgumentNullException("request");

        IHttpRouteData routeData = request.GetRouteData();

        if (routeData == null)
            return null;

       //Look up controller in route data
        object controllerName;
        routeData.Values.TryGetValue("controller", out controllerName);

        if (controllerName != null)
            controllerName += "api";

        return (string)controllerName;
    }
}

Global.asaxに登録する

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
            new ApiControllerSelector(GlobalConfiguration.Configuration));
9
追加された
あなたが単にbase.GetControllerNameを呼び出し、それに "api"を追加すれば、これははるかに簡単になります。しかしそれは正しい考えです。これがうまくいくのを見てうれしい:)
追加された 著者 Youssef Moussaoui,
私は同意する、それはずっときれいだろう。私にストライクしなかった。 :)
追加された 著者 muruge,
私は何かが欠けているに違いない、これは私のために働いていない。私は私のコントローラセレクタが呼び出されているのを見て、それは最後にAPIを返していますが、コントローラが呼び出されることはありません。
追加された 著者 Aaron Stainback,

私はあなたが探している拡張性のポイントはコントローラセレクタだと思います。 DefaultHttpControllerSelectorから派生したクラスを作成し、GetControllerNameをオーバーライドして「api」部分を取り除くことができます。このコントローラーセレクターをサービスの構成サービスに登録することができます。

7
追加された
見るべき場所のように聞こえる。私はそのショットを与え、あなたはそれがどのように進むのかを知らせます。
追加された 著者 muruge,

ASP.NET Web API 2がリリースされたので、属性ルーティングを参照してください。

コントローラの上部に次の属性を追加します。

[RoutePrefix("api/students")]
public class StudentsApiController : ApiController
{
    ...
}

各APIメソッドの前に:

[Route("{id}"]
public HttpResponseMessage Get(int id)
{
    ...
}

少しセットアップが必要ですが、このようにルーティングすることの利点は多くあります。 1つは、実際の作業を行うコントローラーとメソッドを使用してルーティングを行うことができるため、正しいルートがあるかどうか疑問に思うことはありません。さらに重要なのは、複雑なルーティングを行う方が簡単です(コントローラ名をルート名とは異なるようにするなど)。

7
追加された
それでも属性ルーティングを持つ "Controller"接尾辞が必要です。
追加された 著者 angularsen,

ムーアの答えに対するYoussefのコメントに続いて、これは次のようになります

public class ApiControllerSelector : DefaultHttpControllerSelector
{
    public ApiControllerSelector (HttpConfiguration configuration) : base(configuration) { }

    public override string GetControllerName(HttpRequestMessage request)
    {
        return base.GetControllerName(request) + "api";
    }
}
1
追加された