路由与动作选择.docx
- 文档编号:29269867
- 上传时间:2023-07-21
- 格式:DOCX
- 页数:15
- 大小:23.56KB
路由与动作选择.docx
《路由与动作选择.docx》由会员分享,可在线阅读,更多相关《路由与动作选择.docx(15页珍藏版)》请在冰豆网上搜索。
路由与动作选择
【ASP.NETWebAPI教程】4.2路由与动作选择
注:
本文是【ASP.NETWebAPI系列教程】的一部分,如果您是第一次看本系列教程,请先看前面的内容。
4.2RoutingandActionSelection
4.2路由与动作选择
本文引自:
ByMikeWasson|July27,2012
作者:
MikeWasson|日期:
2012-7-27
ThisarticledescribeshowASP.NETWebAPIroutesanHTTPrequesttoaparticularactiononacontroller.
本文描述ASP.NETWebAPI如何把一个HTTP请求路由到控制器的一个特定的方法上。
Forahigh-leveloverviewofrouting,seeRoutinginASP.NETWebAPI.
关于路由的总体概述,参阅“ASP.NETWebAPI中的路由”(本系列教程的前一小节—译者注)。
Thisarticlelooksatthedetailsoftheroutingprocess.IfyoucreateaWebAPIprojectandfindthatsomerequestsdon’tgetroutedthewayyouexpect,hopefullythisarticlewillhelp.
本文考察路由过程的细节。
如果你创建了一个WebAPI项目,并发现有些请求并未按你期望的方式被路由,希望这篇文章对你会有所帮助。
Routinghasthreemainphases:
路由有三个主要阶段:
1.MatchingtheURItoaroutetemplate.
将URI匹配到一个路由模板。
2.Selectingacontroller.
选择一个控制器
3.Selectinganaction.
选择一个动作。
Youcanreplacesomepartsoftheprocesswithyourowncustombehaviors.Inthisarticle,Idescribethedefaultbehavior.Attheend,Inotetheplaceswhereyoucancustomizethebehavior.
你可以用自己的自定义行为来替换这一过程的某些部分。
在本文中,我会描述默认行为。
最后,我会注明可以在什么地方自定义行为。
RouteTemplates
路由模板
AroutetemplatelookssimilartoaURIpath,butitcanhaveplaceholdervalues,indicatedwithcurlybraces:
路由模板看上去类似于一个URI路径,但它可以具有占位符,这是用花括号来指示的:
"api/{controller}/public/{category}/{id}"
Whenyoucreatearoute,youcanprovidedefaultvaluesforsomeoralloftheplaceholders:
当创建一条路由时,可以为某些或所有占位符提供默认值:
defaults:
new{category="all"}
Youcanalsoprovideconstraints,whichrestricthowaURIsegmentcanmatchaplaceholder:
也可以提供约束,它限制URI片段如何与占位符匹配:
constraints:
new{id=@"\d+"}//Onlymatchesif"id"isoneormoredigits.
//用正则表达式限制片段的取值,上语句表明,id片段的值必须是一个或多个数字。
//因此,URI中id片段必须是数字才能与这条路由匹配
TheframeworktriestomatchthesegmentsintheURIpathtothetemplate.Literalsinthetemplatemustmatchexactly.Aplaceholdermatchesanyvalue,unlessyouspecifyconstraints.TheframeworkdoesnotmatchotherpartsoftheURI,suchasthehostnameorthequeryparameters.TheframeworkselectsthefirstrouteintheroutetablethatmatchestheURI.
框架会试图把URI路径的片段与该模板进行匹配。
模板中的文字必须严格匹配。
占位符可以匹配任意值,除非你指定了约束。
框架不会匹配URI的其它部分,如主机名或查询字符串。
框架会选择路由表中与URI匹配的第一条路由。
Therearetwospecialplaceholders:
"{controller}"and"{action}".
有两个特殊的占位符:
“{controller}”和“{action}”。
∙"{controller}"providesthenameofthecontroller.
“{controller}”提供控制器名。
∙"{action}"providesthenameoftheaction.InWebAPI,theusualconventionistoomit"{action}".
“{action}”提供动作名。
在WebAPI中,通常的约定是忽略“{action}”的。
Defaults
默认值
Ifyouprovidedefaults,theroutewillmatchaURIthatismissingthosesegments.Forexample:
如果提供默认值,该路由将能够匹配缺少这些片段的URI。
例如:
routes.MapHttpRoute(
name:
"DefaultApi",
routeTemplate:
"api/{controller}/{category}",
defaults:
new{category="all"}
);
TheURI"http:
//localhost/api/products"matchesthisroute.The"{category}"segmentisassignedthedefaultvalue"all".
URI“http:
//localhost/api/products”与这条路由是匹配的。
“{category}”片段被赋成了默认值“all”。
RouteDictionary
路由字典
IftheframeworkfindsamatchforaURI,itcreatesadictionarythatcontainsthevalueforeachplaceholder.Thekeysaretheplaceholdernames,notincludingthecurlybraces.ThevaluesaretakenfromtheURIpathorfromthedefaults.ThedictionaryisstoredintheIHttpRouteDataobject.
如果框架为一个URI找到一个匹配,它会创建一个字典,其中包含了每个占位符的值。
(字典的内容是一些“键-值”对—译者注)。
其键是不带花括号的占位符名称。
其值取自URI路径或默认值。
该字典被存储在IHttpRouteData对象中。
Duringthisroute-matchingphase,thespecial"{controller}"and"{action}"placeholdersaretreatedjustliketheotherplaceholders.Theyaresimplystoredinthedictionarywiththeothervalues.
在路由匹配阶段,“{controller}”和“{action}”占位符的处理与其它占位符的处理是一样的。
只是把它们简单地用值存储在字典中。
AdefaultcanhavethespecialvalueRouteParameter.Optional.Ifaplaceholdergetsassignedthisvalue,thevalueisnotaddedtotheroutedictionary.Forexample:
在默认值中可以使用特殊的RouteParameter.Optional值。
如果一个占位符被赋予了这个值,则该值不会被添加到路由字典。
例如:
routes.MapHttpRoute(
name:
"DefaultApi",
routeTemplate:
"api/{controller}/{category}/{id}",
defaults:
new{category="all",id=RouteParameter.Optional}
);
FortheURIpath"api/products",theroutedictionarywillcontain:
对于URI路径“api/products”,路由字典将含有:
∙controller:
"products"
∙category:
"all"
由于这条URI路径中不包含id,因此,id的值将采用默认的RouteParameter.Optional,所以,路由字典中不会包含id片段的键值对—译者注
For"api/products/toys/123",however,theroutedictionarywillcontain:
然而,对于“api/products/toys/123”,路由字典将含有:
∙controller:
"products"
∙category:
"toys"
∙id:
"123"
Thedefaultscanalsoincludeavaluethatdoesnotappearanywhereintheroutetemplate.Iftheroutematches,thatvalueisstoredinthedictionary.Forexample:
默认值也可以包含未出现在路由模板中的值。
若这条路由匹配,则该值会被存储在路由字典中。
例如:
routes.MapHttpRoute(
name:
"Root",
routeTemplate:
"api/root/{id}",
defaults:
new{controller="customers",id=RouteParameter.Optional}
);
IftheURIpathis"api/root/8",thedictionarywillcontaintwovalues:
如果URI路径是“api/root/8”,字典将含有两个值:
∙controller:
"customers"
∙id:
"8"
SelectingaController
选择控制器
ControllerselectionishandledbytheIHttpControllerSelector.SelectControllermethod.ThismethodtakesanHttpRequestMessageinstanceandreturnsanHttpControllerDescriptor.ThedefaultimplementationisprovidedbytheDefaultHttpControllerSelectorclass.Thisclassusesastraightforwardalgorithm:
控制器选择是由IHttpControllerSelector.SelectController方法来处理的。
这个方法以HttpRequestMessage实例为参数,并返回HttpControllerDescriptor。
其默认实现是由DefaultHttpControllerSelector类提供的。
这个类使用了一种很直接的算法:
1.Lookintheroutedictionaryforthekey"controller".
查找路由字典的“controller”键。
2.Takethevalueforthiskeyandappendthestring"Controller"togetthecontrollertypename.
取得这个键的值,并附加字符串“Controller”,以得到控制器的类型名。
3.LookforaWebAPIcontrollerwiththistypename.
用这个类型名查找WebAPI控制器。
Forexample,iftheroutedictionarycontainsthekey-valuepair"controller"="products",thenthecontrollertypeis"ProductsController".Ifthereisnomatchingtype,ormultiplematches,theframeworkreturnsanerrortotheclient.
例如,如果路由字典的键-值对为“controller”=“products”,那么,控制器类型便为“ProductsController”。
如果没有匹配类型,或有多个匹配,框架会给客户端返回一条错误。
Forstep3,DefaultHttpControllerSelectorusestheIHttpControllerTypeResolverinterfacetogetthelistofWebAPIcontrollertypes.ThedefaultimplementationofIHttpControllerTypeResolverreturnsallpublicclassesthat(a)implementIHttpController,(b)arenotabstract,and(c)haveanamethatendsin"Controller".
对于步骤3,DefaultHttpControllerSelector使用IHttpControllerTypeResolver接口以获得WebAPI控制器类型的列表。
IHttpControllerTypeResolver的默认实现会返回所有符合以下条件的public类:
(a)实现IHttpController的类(b)是非抽象类,且(c)名称以“Controller”结尾的类。
ActionSelection
动作选择
Afterselectingthecontroller,theframeworkselectstheactionbycallingtheIHttpActionSelector.SelectActionmethod.ThismethodtakesanHttpControllerContextandreturnsanHttpActionDescriptor.
选择了控制器之后,框架会通过调用IHttpActionSelector.SelectAction方法来选择动作。
这个方法以HttpControllerContext为参数,并返回HttpActionDescriptor。
ThedefaultimplementationisprovidedbytheApiControllerActionSelectorclass.Toselectanaction,itlooksatthefollowing:
默认实现是由ApiControllerActionSelector类提供的。
为了选择一个动作,会查找以下方面:
∙TheHTTPmethodoftherequest.
请求的HTTP方法。
∙The"{action}"placeholderintheroutetemplate,ifpresent.
路由模板中的“{action}”占位符(如果有)。
∙Theparametersoftheactionsonthecontroller.
控制器中动作的参数。
Beforelookingattheselectionalgorithm,weneedtounderstandsomethingsaboutcontrolleractions.
在查找选择算法之前,我们需要理解控制器动作的一些事情。
Whichmethodsonthecontrollerareconsidered"actions"?
Whenselectinganaction,theframeworkonlylooksatpublicinstancemethodsonthecontroller.Also,itexcludes"specialname"methods(constructors,events,operatoroverloads,andsoforth),andmethodsinheritedfromtheApiControllerclass.
控制器中的哪些方法被看成为是“动作”?
当选择一个动作时,框架只考察控制器的public实例方法。
而且,它会排除“specialname"特殊名称”的方法(构造器、事件、操作符重载等等),以及继承于ApiController类的方法。
这里按原文的含义似乎是要排除API控制器中的public方法,但译者认为,框架会把API控制器中的public方法看成是动作—译者注
HTTPMethods.TheframeworkonlychoosesactionsthatmatchtheHTTPmethodoftherequest,determinedasfollows:
HTTP方法。
框架只会选择与请求的HTTP方法匹配的动作,确定如下:
1.YoucanspecifytheHTTPmethodwithanattribute:
AcceptVerbs,HttpDelete,HttpGet,HttpHead,HttpOptions,HttpPatch,HttpPost,orHttpPut.
你可以用注解属性AcceptVerbs、HttpDelete、HttpGet、HttpHead、HttpOptions、HttpPatch、HttpPost、或HttpPut来指定HTTP方法(这段文字说明,你可以在方法上用这些注解属性进行标注,以指定该方法用于处理哪一种HTTP请求。
通过这种标注,方法的命名可以不遵循下一条的约定—译者注)。
2.Otherwise,ifthenameofthecontrollermethodstartswith"Get","Post","Put","Delete","Head","Options",or"Patch",thenbyconventiontheactionsupportsthatHTTPmethod.
否则,如果控制器方法名称以“Get”、“Post”、“Put”、“Delete”、“Head”、“Options”、或“Patch”开头,那么,按照约定,该动作支持相应的HTTP方法。
3.Ifnoneoftheabove,themethodsupportsPOST.
如果以上都不是(即,既未用第一条的办法进行标注,又未用第二条的方法命名约定—译者注),则该方法支持POST。
ParameterBindings.AparameterbindingishowWebAPIcreatesavalueforaparameter.Hereisthedefaultruleforparameterbinding:
参数绑定。
参数绑定是指WebAPI如何创建参数值。
以下是参数绑定的默认规则:
∙SimpletypesaretakenfromtheURI.
简单类型取自URI。
∙Complextypesaretakenfromtherequestbody.
复合类型取自请求体。
Simpletypesincludeallofthe.NETFrameworkprimitivetypes,plusDateTime,Decimal,Guid,String,andTimeSpan.Foreachaction,atmostoneparametercanreadtherequestbody.
简单类型包括所有“.NET框架简单类型”,另外还有,DateTime、Decimal、Guid、String和TimeSpan。
对于每一个动作,最多只有一个参数可以读取请求体。
Itispossibletooverridethedefaultbindingrules.SeeWebAPIParameterbindingunderthehood.
也可以重写这种默认的绑定规则。
参见WebAPIParameterbindingunderthehood(作者的一篇博客文章—译者注)。
Withthatbackground,hereistheactionselectionalgorithm.
在这种背景下,动作选择算法如下:
1.Createalistofallactionsonthecontrollerthat
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 路由 动作 选择
![提示](https://static.bdocx.com/images/bang_tan.gif)