WebAPIでのルーティングの調査

ASP.Net Web APIは、ステートレスHTTPサービスを構築するために使用される軽量のフレームワークです。Web APIを使用して、HTTPで実行されるRESTfulサービスを設計および実装できます。RESTはアーキテクチャスタイルであり、ステートレスサービスを実装するために使用される一連の制約です。Web APIは、軽量のHTTPサービスを構築するための最適なテクノロジーになっています。この投稿では、WebAPIでルーティングがどのように機能するかについて説明します。

VisualStudioでWebAPIプロジェクトを作成すると、MVCプロジェクトも作成されていることがわかります。 ASP.Net MVCと同様に、WebAPIプロジェクトのルーティング構成はGlobal.asaxファイルから呼び出されます。 Web APIプロジェクトは、構成情報をRouteConfigクラスとWebApiConfigクラスに格納します。これらは両方ともApplication_Startフォルダーにあります。 MVCプロジェクトと同様に、ソリューションのApp_Startフォルダーに作成されたRouteConfig.csファイルを確認します。

Web APIのコントローラーは、HTTP要求の処理を担当します。コントローラのパブリックメソッドは、アクションメソッドとして知られています。リクエストが受信されるとすぐに、WebAPIランタイムはリクエストを適切なアクションにルーティングしてリクエストを処理します。ここで、呼び出すアクションを決定するために、WebAPIランタイムはルーティングテーブルを利用します。通常のASP.NetMVCアプリケーションとは対照的に、Web APIランタイムは、要求のHTTP動詞を適切なアクションメソッドに一致させることにより、着信要求を適切なコントローラーにルーティングします。

ASP.Net 5(Visual Studio 2015の一部としてまもなくリリースされる予定)には、統合されたコアフレームワークがあります。つまり、単一の外出フレームワーク、単一のモデルバインディングフレームワーク、および1つのフィルターパイプラインがあります。これで、ASP.Net MVC、ASP.Net Web API、およびASP.NetWebページ用の統合コアが1つできました。そのため、要求を処理するコントローラーのタイプは1つだけになりました。これは、ASP.Net MVC、ASP.Net Web API、およびASP.Netアプリケーションに共通です。

デフォルトのMVCルートテンプレートは次のようになります。

{コントローラー} / {アクション} / {id}

対照的に、デフォルトのWebAPIルートは次のようになります。

api/{controller}/{id}

The default route created when you create a new Web API project in Visual Studio looks like this:

public static class WebApiConfig

{

public static void Register(HttpConfiguration config)

{

config.Routes.MapHttpRoute(

name: "DefaultApi",

routeTemplate: "api/{controller}/{id}",

defaults: new { id = RouteParameter.Optional }

);

}

}

Note how the default route is prefixed by "api". It is a good practice to define the routes of your Web API application by prefixing them with "api" to make them distinct from the standard MVC route. On a different note, when you look at the default route for a Web API project, you wouldn't see the "{action}" route parameter -- the Web API runtime maps requests to the appropriate actions based on the HTTP verb of the requests.

However, you can modify the Web API route definition to include an "{action}" parameter. The following code snippet illustrates how the modified WebApiConfig class looks like.

public static class WebApiConfig

{

public static void Register(HttpConfiguration config)

{

config.Routes.MapHttpRoute(

name: "DefaultApi",

routeTemplate: "api/{controller}/{action}/{id}",

defaults: new { id = RouteParameter.Optional }

);

}

}

Now that you have specified "{action}" as part of the route, you need to specify the action when invoking the WebAPI method. Consider the following URL: //idgservice/authors/1

In this URL, idgservice is the name of the domain where the WebAPI has been hosted, authors is the controller name, and 1 is passed as a parameter. However, this wouldn't work if you have defined "{action}" in your route definition. You would need to explicitly mention the action name when calling your WebAPI this this case. Here's the correct URL that includes the action name as part of the URL: //idgservice/authors/GetAuthorDetails/

Note that the action name in the above URL is GetAuthorDetails and has been mentioned as part of the modified URL.

You can also specify the HTTP method for an action using the HttpGet, HttpPut, HttpPost, or HttpDelete attribute. The code snippet given below illustrates how this can be achieved:

public class AuthorsController : ApiController

{

[HttpGet]

public Author GetAuthor(id) {}

}

If you would like to allow multiple HTTP methods for an action, you can take advantage of the AcceptVerbs attribute as shown below:

public class ProductsController : ApiController

{

[AcceptVerbs("GET", "HEAD")]

public Author GetAuthor(id) { }

}

You can also override the action using the ActionName attribute as shown in the code snippet given below:

public class AuthorsController : ApiController

{

[HttpGet]

[ActionName("AuthorDetails")]

public Author GetAuthor(id) {}

}

Note that you can also prevent a method from being invoked as an action by leveraging the NonAction attribute as shown below.

public class AuthorsController : ApiController

{

[HttpGet]

[NonAction]

public Boolean ValidateLogin(id) {}

}