ASP.NET WebApiルーティング構成

16527 ワード

一、ルートの紹介


ASP.NET Web APIルーティングはAPI全体のエントリである.あるリソースにアクセスすることは、ルーティングマッピングによって対応するリソースのURLを見つけることです.URLでリソースを取得します.
ASPについてNET Web APIの内部実装では,我々の要求は最終的に特定のActionに位置づけられる.だから、ASP.NET Web APIルーティングとは,クライアント要求を対応するActionにマッピングするプロセスである.
 

二、二種類のルーティングモード


2.1テンプレートルーティング


テンプレートルーティングはASP.NET Web APIがデフォルトで提供するルーティング.以下、この理由の使い方を簡単に説明します.
デフォルトテンプレートルーティング
テンプレートルーティングを使用する前に、ルーティングテンプレートを定義する必要があります.次のデフォルトのルーティングテンプレートのように、

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http; namespace Supernova.Webapi { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API // Web API config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } } }

このテンプレートルーティングは、新しいプロジェクトのデフォルトで生成され、App_スタートフォルダの下.
このテンプレートのURLフォーマットはapi/{controller}/{id}であることがわかります.apiはリソースの前にapiディレクトリを持ち、controllerはリソースを要求するコントローラ名を表します.idはリソースのidを表し、idはオプションです.このデフォルトのテンプレートはactionを持たないので、リソースをリクエスト方式で区別します.actionにリクエスト方式の特性を追加して区別する必要があります.
1.テストコントローラapiを追加します.
 

public class TestController : ApiController { public object Get1() { return "d1"; } }

fiddldrで次のようにデバッグします.
2.次の2つの方法を追加します.
 

public class TestController : ApiController { public object Get1() { return "d1"; } public object Get2() { return "d2"; } }

 
fiddlerで次のようにデバッグします.
エラーメッセージは次のとおりです.
{「Message」:「エラーが発生しました.」「ExceptionMessage」:「rタイプSupernova.Webapi.controller.TestControllerのGet 1rタイプSupernova.Webapi.controller.TestControllerのGet 2」、「ExceptionType」:「System.InvalidOperationException」、「StackTrace」:「System.Web.Http.C ontroller.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction( HttpControllerContext controllerContext)rでSystem.Web.Http.ApiController.ExecuteAsync(HttpControllerContext contrtrollerContext,CancellattionToken)rでSystem.Web.Http.Dispatcher.Http.ControllerDispatcher.d__1.MoveNext()
コードを次のように変更します.
 

public class TestController : ApiController { public object Get1() { return "d1"; } [HttpPost] public object Get2() { return "d2"; } }

デバッグはGet 1の情報を返します.
上記の2つのテストから、次の結論を得ることができます.
  • actionのデフォルトリクエスト方式はHttpGetです.
  • 複数のactionの要求方式が同じであれば、デフォルトのルーティングテンプレートの下(actionなし)で複数の操作が一致する.
  • 上記の2つの結論に基づいて、デフォルトのルーティングテンプレートは、1つのリソースに対する要求方式の複数の操作(例えば、変更操作、異なるフィールドに対する変更)を満たすことができない.

  • カスタムテンプレートルーティング
    テンプレートルーティングを再カスタマイズします.次のようにします.
     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http; namespace Supernova.Webapi { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API // Web API config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); } } }

    以上から,デフォルトルーティングに基づいて,我々のキュールーティングテンプレートは1次actionを追加したことが分かる.
    テストapiは次のとおりです.
     

    public class TestController : ApiController { public object Get1() { return "d1"; } public object Get2() { return "d2"; } }

    僕らはまたhttp://192.168.0.230/api/testアクセスして、図のように404を返す.
    我々はhttp://192.168.0.230/api/test/Get1図のように、アクセス結果が正しい:
    我々はhttp://192.168.0.230/api/test/Get2図のように、アクセス結果が正しい:
     
    ルーティングテンプレートをカスタマイズすることで、次の結論を得ることができます.
  • は、ルーティングテンプレートにactionディレクトリを追加することによって、リソースの位置決めをactionに直接作用させる.
  • の複数のHttpGet法は、1つのコントローラに共存することができる.
  • は、上記の2つの結論に基づいて、ルーティングテンプレートを変更することによって、1つのリソースに対する要求方式の複数の動作を満たすことができる.

  •  

    2.2特性ルーティング


    プロパティルーティングはactionにattributeを打つことによってルーティングルールを定義します.
    時には、サブリソースを持つリソースを要求する必要があります.例えば、文章はこのような関連関係のあるリソースを評論します.ある記事のコメント:api/book/id/commentsを以下のURLで入手したいと考えています.テンプレートルーティングだけでは,このルーティングモードを実現することは困難である.この時、私たちはこの問題を解決するために特性の道が必要です.ASP.NET Web APIは、アクションに直接打てる柔軟性と直感性を備えたRouteプロパティを用意しています.
    まず、プロパティルーティングの使用方法について簡単に説明します.
    apiを再定義するには、次のようにします.

    public class TestController : ApiController { [Route("demo")] [HttpGet] public object Get1() { return "d1"; } [Route("demo/get")] [HttpGet] public object Get2() { return "d2"; } }

    actionにラベルをつけたことがわかります.
    fiddlerを使用して次のようにデバッグします.
    Get 1を要求するURLはhttp://192.168.0.230/demo
    Get 2を要求するURLはhttp://192.168.0.230/demo/get

    2.3 2つのルーティングの比較

  • テンプレートルーティングピンは、単純なビジネスに非常に便利であるが、複雑なリソース操作にはわずかな余力が不足している.
  • プロパティルーティングは、action名を変更することなく柔軟に変更できます.
  • プロパティルーティングは、関連リソースに対して友好的なURLを作成することができる.
  • 特性ルーティングは、ルーティングパラメータの制約に対して微細化制御を果たすことができる.

  • 三、特性ルーティングの詳細


    3.1 Routeプロパティの使用


    特性ルーティングを使用するのは簡単で、追加の構成をする必要はなく、actionにRouteラベルを付けるだけでいいです.これでテンプレートルーティングは自動的に失効します.
    次のようになります.

    public class TestController : ApiController { [Route("demo")] [HttpGet] public object Get1() { return "d1"; } [Route("demo/get")] [HttpGet] public object Get2() { return "d2"; } }

    3.2 RoutePrefixプロパティの使用


    あるリソースのすべての操作に統一的な接頭辞を付けたい場合があります.
    1つ目の方法:

    public class TestController : ApiController { [Route("api/demo")] [HttpGet] public object Get1() { return "d1"; } [Route("api/demo/get")] [HttpGet] public object Get2() { return "d2"; } }

    この方法はまあまあですが、少し知恵が弱いです.では、RoutePrefixを使用してコントローラにプロパティを追加すると、リソースのリクエストにapiディレクトリが追加されます.
    2つ目の方法:

    [RoutePrefix("api")] public class TestController : ApiController { [Route("demo")] [HttpGet] public object Get1() { return "d1"; } [Route("demo/get")] [HttpGet] public object Get2() { return "d2"; } }

    3.3 Actionのプレフィックス規則を書き換える


    3.2の方法は、あるリソースの前にプレフィックスを統一的に付けることができる.では、問題が来ました.もし私たちがこのような需要があれば、私のあるリソースの大部分のリクエストには接頭辞が必要ですが、1、2つのリソースに接頭辞を加える必要はありません.腫れていますか.実はマイクロソフトはとっくに私たちに考えてくれました.人が言ったように、もちろんaction接頭辞を書き直すことを許してください.
    次のコードでGet 1を再構築しました.

    [RoutePrefix("api")] public class TestController : ApiController { [Route("~/demo")] [HttpGet] public object Get1() { return "d1"; } [Route("demo/get")] [HttpGet] public object Get2() { return "d2"; } }

    fiddlerで次のようにデバッグします.
    間違いを報告したでしょう.正しいURLは実は:http://192.168.0.230/demo

    3.4.1ルーティングパラメータ制約


    今また問題が来て、そんなに多くの要求、特にGet要求方式、すべてパラメータを持つ必要があります、どのようにパラメータのタイプ、長さの範囲などの制約条件を定義しますか?
    答えは「{パラメータ変数名:制約}」でルーティング内のパラメータ変数を制約できることです.
    ASP.NET Web API内蔵制約には、{x:alpha}制約大文字小文字{x:bool}{x:datetime}{x:decimal}{x:double}{x:float}{x:guid}{x:int}{x:length(6)}{x:length(1,20)}制約長範囲{x:long}{x:maxlength(10)}{x:min(10)}{x:range(10,50)}{x:regex(正規表現)}が含まれます.
    次のコードがあります.

    [RoutePrefix("api")] public class TestController : ApiController { [Route("demo/{id:int}")] [HttpGet] public object Get1() { return "d1"; } [Route("demo/{name}")] [HttpGet] public object Get2() { return "d2"; } }

    以上、フラグメント変数idがintタイプである場合、第1のActionGet 1にルーティングし、そうでない場合、第2のActionGet 2にルーティングする.
    fiddlerを使用して次のようにデバッグします.
    要求はGet 1である.
    リクエストはGet 2
    1つのパラメータ変数に対して複数のコンストレイントを同時に設定できます.
    次のコードがあります.

    [RoutePrefix("api")] public class TestController : ApiController { [Route("demo/{id:int:min(5)}")] [HttpGet] public object Get1() { return "d1"; } [Route("demo/{name}")] [HttpGet] public object Get2() { return "d2"; } }

    要求URL:http://192.168.0.230/api/demo/1Get 2への位置決め

    3.4.2拡張ルーティングパラメータ制約


    IHttpRouteConstraintインタフェースを実装し、制約ルールをカスタマイズできます.0にできないコンストレイントを実装します.
    コードは次のとおりです.

    public class NonZeroConstraint : IHttpRouteConstraint { public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary values, HttpRouteDirection routeDirection) { object value; if (values.TryGetValue(parameterName, out value) && value != null) { long longValue; if (value is long) { longValue = (long)value; return longValue != 0; } string valueString = Convert.ToString(value, CultureInfo.InvariantCulture); if (Int64.TryParse(valueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out longValue)) { return longValue != 0; } } return false; } }

    App_StartフォルダのWebApiConfigにカスタム制約を登録します.元のテンプレートルーティングにコメントする必要があります

    public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API // Web API //config.MapHttpAttributeRoutes(); //config.Routes.MapHttpRoute( // name: "DefaultApi", // routeTemplate: "api/{controller}/{action}/{id}", // defaults: new { id = RouteParameter.Optional } //); var constraintResolver = new DefaultInlineConstraintResolver(); constraintResolver.ConstraintMap.Add("nonzero", typeof(NonZeroConstraint)); config.MapHttpAttributeRoutes(constraintResolver); } }

    テストコードは次のとおりです.

    [RoutePrefix("api")] public class TestController : ApiController { [Route("demo/{id:nonzero}")] [HttpGet] public object Get1() { return "d1"; } [Route("demo/{name}")] [HttpGet] public object Get2() { return "d2"; } }

    URLの使用:http://192.168.0.230/api/demo/0Get 2への位置決め

    3.5オプションのパラメータとそのデフォルト


    時々、私たちが要求したパラメータはオプションですが、どうすればいいのでしょうか.パラメータにデフォルト値を設定して処理する必要があります.
    コードは次のとおりです.

    [RoutePrefix("api")] public class TestController : ApiController { [Route("demo/{id:int?}")] [HttpGet] public object Get1(int id=1) { return "d1"+id; } [Route("demo/{name}")] [HttpGet] public object Get2() { return "d2"; } }

    パラメータが存在しない場合、またはintタイプである場合にはGet 1、パラメータが存在しない場合にはGet 2が位置する.
    URL:http://192.168.0.230/api/demo位置決めGet 1 URL:http://192.168.0.230/api/demo/2位置決めGet 1 URL:http://192.168.0.230/api/demo/abc位置決めGet 2

    3.6ルーティングの名前


    [RoutePrefix("api")] public class TestController : ApiController { [Route("demo/{id:int?}",Name=" ID ")] [HttpGet] public object Get1(int id = 1) { return "d1" + id; } [Route("demo/{name}")] [HttpGet] public object Get2() { return "d2"; } }

    3.7ルーティング優先順位


     
    Routeプロパティ設定のルーティング優先順位は、慣例とRouteOrderプロパティに基づいて決定されます.
    慣例は次のとおりです.
    1、静的フラグメント変数2、制約付きフラグメント変数3、制約なしフラグメント変数4、制約付きワイルドカードフラグメント変数5、制約なしワイルドカードフラグメント変数
    RouteOrder属性のデフォルト値は0で、属性値が小さいほど前に並びます.
    テストコードは次のように優先されます.

    [RoutePrefix("api")] public class TestController : ApiController { [Route("orders/detail", Name = " ")] [HttpGet] public object Get1() { return "orders/detail"; } [Route("orders/{id:int}", Name = " ")] [HttpGet] public object Get2(int id) { return "orders/{id:int}"; } [Route("orders/{name}", Name = " ")] [HttpGet] public object Get3(string name) { return "orders/{name}"; } [Route("orders/lily", Order = 1)] [HttpGet] public object Get4() { return "orders/lily"; } }

    URL:http://192.168.0.230/api/orders/detail位置決めGet 1静的フラグメント変数Order=0
    URL:http://192.168.0.230/api/orders/lilyGet 3拘束付きフラグメント変数Order=0を位置決めする
    URL:http://192.168.0.230/api/orders/1Get 2非拘束フラグメント変数Order=0を配置
    Get 3にはGet 4の定義が含まれているので、Get 4には永遠に定義できません.これも特性ルーティングにおいて特に注意すべき点である.

    3.8ルーティング仕様


    1.URLに動詞は表示されません. 
    参照先:
    http://www.eggtwo.com/news/detail/155
    https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
    http://www.cnblogs.com/n-pei/archive/2012/07/17/2595352.html