在ASP.NET、ASP.NET MVC和ASP.NET Web API中這些框架中都會(huì)發(fā)現(xiàn)有路由的身影,它們的原理都差不多,只不過(guò)在不同的環(huán)境下作了一些微小的修改,這也是根據(jù)每個(gè)框架的特性來(lái)制定的,今天我們就來(lái)看一看路由的結(jié)構(gòu),雖然我在MVC系列里寫(xiě)過(guò)路由的篇幅不過(guò)在這里是Web API 路由對(duì)象介紹。

ASP.NET Web API 開(kāi)篇介紹示例
ASP.NET Web API 路由對(duì)象介紹
ASP.NET Web API 管道模型
ASP.NET Web API selfhost宿主環(huán)境中管道、路由
ASP.NET Web API webhost宿主環(huán)境中管道、路由
路由系統(tǒng)概念
路由的結(jié)構(gòu)
圖1

路由系統(tǒng)中最重要的部分也就是路由對(duì)象了,那我們首先就來(lái)看一下【路由對(duì)象】的定義,不管是在ASP.NET、ASP.NET MVC、還是ASP.NET Web API的路由系統(tǒng)中路由都要有個(gè)名稱,其實(shí)這個(gè)名稱并不是路由對(duì)象中的而是在注冊(cè)路由信息的時(shí)候,添加到路由對(duì)象集合的時(shí)候需要的名稱,這里也只是當(dāng)作路由的一部分,這個(gè)大家知道就好了。
在生成路由對(duì)象的時(shí)候我們要給路由賦值URL模板,這也是共同的,也是必須的,至于約束URL模板的條件是可以根據(jù)自己情況來(lái)定義的。在生成的同時(shí)框架會(huì)給路由對(duì)象賦值上【路由請(qǐng)求處理程序】用以作為銜接路由系統(tǒng)和框架的主體功能部分。
注冊(cè)路由到系統(tǒng)框架中
圖2

在路由定義好之后,我們便會(huì)把它注冊(cè)到系統(tǒng)框架中。
路由對(duì)象的URL匹配
圖3

在路由對(duì)象注冊(cè)到系統(tǒng)框架中之后,這個(gè)時(shí)候如果有外部的請(qǐng)求的到達(dá),這個(gè)時(shí)候路由系統(tǒng)會(huì)讓路由對(duì)象集合中每個(gè)路由對(duì)象對(duì)這個(gè)請(qǐng)求進(jìn)行匹配,就如圖4一樣。
圖4

這個(gè)時(shí)候就是路由對(duì)象所要能做出的行為就是URL的匹配,根據(jù)什么來(lái)匹配?是根據(jù)在路由對(duì)象實(shí)例化的時(shí)候定義好的URL模板和條件,拿請(qǐng)求信息的URL和自身定義的URL模板進(jìn)行匹配,假使沒(méi)有匹配成功則會(huì)返回Null,這個(gè)時(shí)候框架則會(huì)讓下一個(gè)路由對(duì)象來(lái)進(jìn)行匹配直到有匹配的成功為止,如果這個(gè)時(shí)候匹配成功了路由則會(huì)生成一個(gè)【路由數(shù)據(jù)對(duì)象】。
路由數(shù)據(jù)對(duì)象也很重要,因?yàn)楹罄m(xù)的框架功能部分都是使用它的,它也是整個(gè)路由系統(tǒng)的結(jié)晶,我們看下圖5
圖5

路由數(shù)據(jù)對(duì)象會(huì)保持一個(gè)生成它的路由對(duì)象的引用,然后是Values的是保存著路由對(duì)象在經(jīng)過(guò)URL匹配后的值,分別表示著URL片段的名字和對(duì)應(yīng)的URL真實(shí)值,而DataTokens則是在路由對(duì)象定義生成的時(shí)候直接帶過(guò)來(lái)的值,當(dāng)然了路由請(qǐng)求處理程序也是由執(zhí)行生成的路由對(duì)象帶來(lái)的。
在ASP.NET、ASP.NET MVC、ASP.NET Web API這些框架中路由系統(tǒng)都是遵循著上面的所述的這樣一個(gè)過(guò)程,只不過(guò)在不同的框架環(huán)境下使用的類(lèi)型不同,做的處理也不太一樣,但是整體的流程是一致的,下面附上圖6說(shuō)明了之間的類(lèi)型的差異性,還有更多的細(xì)節(jié)就不一一展示了。
圖6

還有在Web API(WebHost)環(huán)境下路由顯示的是這樣實(shí)質(zhì)的本質(zhì)其實(shí)又是ASP.NET的路由系統(tǒng)在支持的,這個(gè)會(huì)在后面的Web API系列篇幅中講解。
下面簡(jiǎn)單的演示一下在各種框架環(huán)境下的路由對(duì)象注冊(cè),
ASP.NET:
RouteTable.Routes.MapPageRoute(
"ASP.NETRoute",
"ProductInfo/{action}/{id}",
"~/ProductInfo.aspx",
true,
newRouteValueDictionary { {"id", RouteParameter.Optional }, { "action", "show" } }
);ASP.NET MVC:
RouteTable.Routes.MapRoute(
"ASP.NETMVCRoute",
"ProductInfo/{action}/{id}",
new { controller="Product",action="show",id=RouteParameter.Optional}
);ASP.NET Web API(WEBHOST):
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
"WebAPIRoute",
"api/{controller}/{id}", new { id=RouteParameter.Optional }
);ASP.NET Web API(SELFHOST):
HttpSelfHostConfigurationconfiguration=
newHttpSelfHostConfiguration("http://loacalhost/selfhost");
using (HttpSelfHostServerselfHostServer=newHttpSelfHostServer(configuration))
{
selfHostServer.Configuration.Routes.MapHttpRoute(
"DefaultApi", "api/{controller}/{id}", new { id=RouteParameter.Optional});
selfHostServer.OpenAsync();
Console.Read();
}ASP.NET Web API路由系列對(duì)象
從上圖的圖表中就可以看出,ASP.NET Web API框架在不同的宿主環(huán)境下路由系統(tǒng)中所對(duì)應(yīng)的對(duì)象類(lèi)型是不同的,這里就先給大家介紹在SelfHost環(huán)境下的路由系統(tǒng)中的路由對(duì)象吧。
SelfHost宿主環(huán)境
Web API路由對(duì)象(System.Web.Http.Routing)
HttpRoute
// 摘要:
// 表示自承載(即在 ASP.NET 之外承載)的路由類(lèi)。
publicclassHttpRoute : IHttpRoute
{
publicHttpRoute(stringrouteTemplate, HttpRouteValueDictionarydefaults, HttpRouteValueDictionaryconstraints, HttpRouteValueDictionarydataTokens, HttpMessageHandlerhandler);
publicIDictionary<string, object>Constraints { get; }
publicIDictionary<string, object>DataTokens { get; }
publicIDictionary<string, object>Defaults { get; }
publicHttpMessageHandlerHandler { get; }
publicstringRouteTemplate { get; }
publicvirtualIHttpRouteDataGetRouteData(stringvirtualPathRoot, HttpRequestMessagerequest);
publicvirtualIHttpVirtualPathDataGetVirtualPath(HttpRequestMessagerequest, IDictionary<string, object>values);
protectedvirtualboolProcessConstraint(HttpRequestMessagerequest, objectconstraint, stringparameterName, HttpRouteValueDictionaryvalues, HttpRouteDirectionrouteDirection);
}可以從上面的定義中看到HttpRoute對(duì)象就是代表著在Web API框架中的路由對(duì)象了,在HttpRoute類(lèi)型定義的構(gòu)造函數(shù)中的參數(shù)分別表示著路由模板、路由模板對(duì)應(yīng)的默認(rèn)值、路由匹配條件、注冊(cè)的路由附帶的值以及最后的Http請(qǐng)求處理程序,這幾個(gè)參數(shù)值也分別對(duì)應(yīng)著HttpRoute類(lèi)型中的幾個(gè)屬性,這個(gè)自行看一下就明白了。
Web API路由對(duì)象集合(System.Web.Http)
HttpRouteCollection
HttpRouteCollectionExtensions
我們先來(lái)看一下HttpRouteCollection類(lèi)型的擴(kuò)展類(lèi)型HttpRouteCollectionExtensions吧
publicstaticclassHttpRouteCollectionExtensions
{
publicstaticIHttpRouteMapHttpRoute(thisHttpRouteCollectionroutes, stringname, stringrouteTemplate);
publicstaticIHttpRouteMapHttpRoute(thisHttpRouteCollectionroutes, stringname, stringrouteTemplate, objectdefaults);
publicstaticIHttpRouteMapHttpRoute(thisHttpRouteCollectionroutes, stringname, stringrouteTemplate, objectdefaults, objectconstraints);
publicstaticIHttpRouteMapHttpRoute(thisHttpRouteCollectionroutes, stringname, stringrouteTemplate, objectdefaults, objectconstraints, HttpMessageHandlerhandler);
}這里大家可以對(duì)比上面的路由注冊(cè)時(shí)的代碼,就可以知道我們?cè)诼酚杉咸砑?注冊(cè)路由的時(shí)候是由HttpRouteCollectionExtensions類(lèi)型的擴(kuò)展方法來(lái)進(jìn)行操作的,這個(gè)時(shí)候我們?cè)倏匆幌路椒▍?shù)最多的那個(gè)MapHttpRoute()方法的實(shí)現(xiàn):
publicstaticIHttpRouteMapHttpRoute(thisHttpRouteCollectionroutes, stringname, stringrouteTemplate, objectdefaults, objectconstraints, HttpMessageHandlerhandler)
{
if (routes==null)
{
throwSystem.Web.Http.Error.ArgumentNull("routes");
}
HttpRouteValueDictionarydictionary=newHttpRouteValueDictionary(defaults);
HttpRouteValueDictionarydictionary2=newHttpRouteValueDictionary(constraints);
IDictionary<string, object>dataTokens=null;
HttpMessageHandlerhandler2=handler;
IHttpRouteroute=routes.CreateRoute(routeTemplate, dictionary, dictionary2, dataTokens, handler2);
routes.Add(name, route);
returnroute;
}這里大家就可以看到了,HttpRoute對(duì)象的創(chuàng)建操作和添加操作是在這擴(kuò)展方法里執(zhí)行的,現(xiàn)在我們就可以去看一下HttpRouteCollection類(lèi)型的定義了,看一下如何創(chuàng)建的IHttpRoute對(duì)象:
publicclassHttpRouteCollection : ICollection<IHttpRoute>, IEnumerable<IHttpRoute>, IEnumerable, IDisposable
{
publicHttpRouteCollection();
publicHttpRouteCollection(stringvirtualPathRoot);
publicvirtualintCount { get; }
publicvirtualboolIsReadOnly { get; }
publicvirtualstringVirtualPathRoot { get; }
publicvirtualvoidAdd(stringname, IHttpRouteroute);
publicIHttpRouteCreateRoute(stringrouteTemplate, objectdefaults, objectconstraints);
publicIHttpRouteCreateRoute(stringrouteTemplate, IDictionary<string, object>defaults, IDictionary<string, object>constraints, IDictionary<string, object>dataTokens);
publicvirtualIHttpRouteCreateRoute(stringrouteTemplate, IDictionary<string, object>defaults, IDictionary<string, object>constraints, IDictionary<string, object>dataTokens, HttpMessageHandlerhandler);
publicvirtualIHttpRouteDataGetRouteData(HttpRequestMessagerequest);
}這里只是其中的一部分,下面我們就來(lái)看一下具體的實(shí)現(xiàn),其實(shí)就是實(shí)例化一個(gè)HttpRoute路由對(duì)象根據(jù)用戶配置的參數(shù)信息:
publicvirtualIHttpRouteCreateRoute(stringrouteTemplate, IDictionary<string, object>defaults, IDictionary<string, object>constraints, IDictionary<string, object>dataTokens, HttpMessageHandlerhandler)
{
HttpRouteValueDictionarydictionary=newHttpRouteValueDictionary(defaults);
HttpRouteValueDictionarydictionary2=newHttpRouteValueDictionary(constraints);
returnnewHttpRoute(routeTemplate, dictionary, dictionary2, newHttpRouteValueDictionary(dataTokens), handler);
}這是路由對(duì)象集合類(lèi)型的第一個(gè)作用就是添加/注冊(cè)路由信息,那么第二個(gè)呢?就是根據(jù)請(qǐng)求信息來(lái)匹配路由對(duì)象,上面也說(shuō)過(guò)了,其實(shí)真正根據(jù)請(qǐng)求來(lái)匹配的并不是路由對(duì)象集合類(lèi)型(HttpRouteCollection),而是在其中的每個(gè)路由,我們看一下HttpRouteCollection的障眼法:
publicvirtualIHttpRouteDataGetRouteData(HttpRequestMessagerequest)
{
if (request==null)
{
throwSystem.Web.Http.Error.ArgumentNull("request");
}
foreach (IHttpRouterouteinthis._collection)
{
IHttpRouteDatarouteData=route.GetRouteData(this._virtualPathRoot, request);
if (routeData!=null)
{
returnrouteData;
}
}
returnnull;
}從這里可以看出在路由匹配完成后會(huì)返回一個(gè)實(shí)現(xiàn)IHttpRouteDatarouteData接口的對(duì)象,也就是上面所說(shuō)的路由數(shù)據(jù)對(duì)象。
Web API路由數(shù)據(jù)對(duì)象(System.Web.Http.Routing)
HttpRouteData
publicclassHttpRouteData : IHttpRouteData
{
publicHttpRouteData(IHttpRouteroute);
publicHttpRouteData(IHttpRouteroute, HttpRouteValueDictionaryvalues);
publicIHttpRouteRoute { get; }
publicIDictionary<string, object>Values { get; }
}其實(shí)這里都不用講了,上面都講過(guò)了,HttpRouteData對(duì)象包含著生成它的路由對(duì)象(HttpRoute)的引用,并且Values值就是經(jīng)過(guò)匹配過(guò)后的路由模板值,key鍵對(duì)應(yīng)著Url模板的片段值,value對(duì)應(yīng)著的是片段對(duì)應(yīng)的真實(shí)值。
SelfHost環(huán)境下的路由就說(shuō)到這里,大家看一下如下的示意圖,簡(jiǎn)單的表示了在SelfHost環(huán)境下路由的一個(gè)處理過(guò)程,具體的細(xì)節(jié)會(huì)在后面的篇幅講解。
圖7

WebHost宿主環(huán)境
Web API路由對(duì)象(System.Web.Http.WebHost.Routing)
HostedHttpRoute
internalclassHostedHttpRoute : IHttpRoute
{
//Methods
publicHostedHttpRoute(stringuriTemplate, IDictionary<string, object>defaults, IDictionary<string, object>constraints, IDictionary<string, object>dataTokens, HttpMessageHandlerhandler);
publicIHttpRouteDataGetRouteData(stringrootVirtualPath, HttpRequestMessagerequest);
publicIHttpVirtualPathDataGetVirtualPath(HttpRequestMessagerequest, IDictionary<string, object>values);
//Properties
publicIDictionary<string, object>Constraints { get; }
publicIDictionary<string, object>DataTokens { get; }
publicIDictionary<string, object>Defaults { get; }
publicHttpMessageHandlerHandler { get; privateset; }
internalRouteOriginalRoute { get; privateset; }
publicstringRouteTemplate { get; }
}從上面的代碼定義中可以看到HostedHttpRoute是程序集內(nèi)部類(lèi)型,并且是直接繼承自IHttpRoute接口,跟SelfHost環(huán)境中的HttpRoute對(duì)象是一點(diǎn)關(guān)系都沒(méi)有。
從它定義的內(nèi)部結(jié)構(gòu)來(lái)看它跟HttpRoute對(duì)象的結(jié)構(gòu)相似,還是那些屬性那些個(gè)對(duì)象,唯一不同的就是多了個(gè)OriginalRoute的只讀屬性(對(duì)于外部來(lái)說(shuō)),這個(gè)屬性也就是封裝的HttpWebRoute對(duì)象,看下封裝時(shí)的實(shí)現(xiàn)
publicHostedHttpRoute(stringuriTemplate, IDictionary<string, object>defaults, IDictionary<string, object>constraints, IDictionary<string, object>dataTokens, HttpMessageHandlerhandler)
{
RouteValueDictionarydictionary= (defaults!=null) ?newRouteValueDictionary(defaults) : null;
RouteValueDictionarydictionary2= (constraints!=null) ?newRouteValueDictionary(constraints) : null;
RouteValueDictionarydictionary3= (dataTokens!=null) ?newRouteValueDictionary(dataTokens) : null;
this.OriginalRoute=newHttpWebRoute(uriTemplate, dictionary, dictionary2, dictionary3, HttpControllerRouteHandler.Instance, this);
this.Handler=handler;
}在HostedHttpRoute對(duì)象構(gòu)造函數(shù)中可以清楚的看到OriginalRoute屬性是賦值的HttpWebRoute對(duì)象的實(shí)例,我們現(xiàn)在就來(lái)看一下HttpWebRoute對(duì)象的定義:
internalclassHttpWebRoute : Route
{
//Fields
internalconststringHttpRouteKey="httproute";
//Methods
publicHttpWebRoute(stringurl, RouteValueDictionarydefaults, RouteValueDictionaryconstraints, RouteValueDictionarydataTokens, IRouteHandlerrouteHandler, IHttpRoutehttpRoute);
privatestaticHttpRouteDirectionConvertRouteDirection(RouteDirectionrouteDirection);
privatestaticRouteValueDictionaryGetRouteDictionaryWithoutHttpRouteKey(IDictionary<string, object>routeValues);
publicoverrideVirtualPathDataGetVirtualPath(RequestContextrequestContext, RouteValueDictionaryvalues);
protectedoverrideboolProcessConstraint(HttpContextBasehttpContext, objectconstraint, stringparameterName, RouteValueDictionaryvalues, RouteDirectionrouteDirection);
//Properties
publicIHttpRouteHttpRoute { get; privateset; }
}從這里可以看到HttpWebRoute對(duì)象繼承自ASP.NET中的Route對(duì)象,現(xiàn)在就可以理解為HostedHttpRoute對(duì)象持有對(duì)ASP.NET中Route對(duì)象的引用,而在HostedHttpRoute的構(gòu)造函數(shù)實(shí)現(xiàn)中,對(duì)OriginalRoute屬性是賦值實(shí)例化的時(shí)候,在最后傳入了一個(gè)HttpControllerRouteHandler類(lèi)型的路由處理程序,實(shí)則是給ASP.NET中的Route對(duì)象的路由處理程序(Routehandler屬性)進(jìn)行的賦值。這里路由的具體的操作后續(xù)篇幅中會(huì)有講到一個(gè)全面的過(guò)程。
Web API路由對(duì)象集合(System.Web.Http.WebHost.Routing
HostedHttpRouteCollection
internalclassHostedHttpRouteCollection : HttpRouteCollection
{
//Fields
privatereadonlyRouteCollection_routeCollection;
//Methods
publicHostedHttpRouteCollection(RouteCollectionrouteCollection);
publicoverridevoidAdd(stringname, IHttpRouteroute);
publicoverridevoidClear();
publicoverrideboolContains(IHttpRouteitem);
publicoverrideboolContainsKey(stringname);
publicoverridevoidCopyTo(IHttpRoute[] array, intarrayIndex);
publicoverridevoidCopyTo(KeyValuePair<string, IHttpRoute>[] array, intarrayIndex);
publicoverrideIHttpRouteCreateRoute(stringuriTemplate, IDictionary<string, object>defaults, IDictionary<string, object>constraints, IDictionary<string, object>dataTokens, HttpMessageHandlerhandler);
publicoverrideIEnumerator<IHttpRoute>GetEnumerator();
publicoverrideIHttpRouteDataGetRouteData(HttpRequestMessagerequest);
publicoverrideIHttpVirtualPathDataGetVirtualPath(HttpRequestMessagerequest, stringname, IDictionary<string, object>values);
publicoverridevoidInsert(intindex, stringname, IHttpRoutevalue);
privatestaticNotSupportedExceptionNotSupportedByHostedRouteCollection();
privatestaticNotSupportedExceptionNotSupportedByRouteCollection();
publicoverrideboolRemove(stringname);
publicoverrideboolTryGetValue(stringname, outIHttpRouteroute);
//Properties
publicoverrideintCount { get; }
publicoverrideIHttpRoutethis[stringname] { get; }
publicoverrideIHttpRoutethis[intindex] { get; }
publicoverridestringVirtualPathRoot { get; }
}看到這里的代碼定義,HostedHttpRouteCollection對(duì)象同樣也是程序集內(nèi)部類(lèi)型,繼承自ASP.NET中的RouteCollection對(duì)象,這里要說(shuō)是CreateRoute()方法和GetRouteData()方法返回的分別是HostedHttpRoute對(duì)象和HostedHttpRouteData對(duì)象,其實(shí)在GetRouteData()方法中起初生成的就是Routedata對(duì)象,只不過(guò)在返回的時(shí)候經(jīng)過(guò)HostedHttpRouteData對(duì)象封裝了一下。
Web API路由數(shù)據(jù)對(duì)象(System.Web.Http.WebHost.Routing)
HostedHttpRouteData
這里我們看一下HostedHttpRouteData類(lèi)型的定義:
internalclassHostedHttpRouteData : IHttpRouteData
{
//Methods
publicHostedHttpRouteData(RouteDatarouteData);
//Properties
internalRouteDataOriginalRouteData { get; privateset; }
publicIHttpRouteRoute { get; privateset; }
publicIDictionary<string, object>Values { get; }
}從構(gòu)造函數(shù)的定義就可以看出來(lái)是HostedHttpRouteData是封裝的RouteData對(duì)象,這些路由流程細(xì)節(jié)后面篇幅中會(huì)有講解。
最后我們看一下在WebHost宿主環(huán)境下的路由示意圖。
圖8

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
文章題目:ASP.NETWebAPI路由對(duì)象介紹-創(chuàng)新互聯(lián)
本文來(lái)源:http://chinadenli.net/article28/piicp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、做網(wǎng)站、微信公眾號(hào)、建站公司、Google、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容