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つのテストから、次の結論を得ることができます.
カスタムテンプレートルーティング
テンプレートルーティングを再カスタマイズします.次のようにします.
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図のように、アクセス結果が正しい:
ルーティングテンプレートをカスタマイズすることで、次の結論を得ることができます.
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つのルーティングの比較
三、特性ルーティングの詳細
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