ASP.NET MVC 4 WebAPI. Support Areas in HttpControllerSelector
2014-02-27 17:11
661 查看
ThisarticlewaswrittenforASP.NETMVC4RC(ReleaseCandidate).IfyouarestillusingBetaversionofASP.NETMVC4thenyouhavetoreadthepreviousarticle.
HttpControllerFactorywasdeletedinASP.NETMVC4RC.Actually,itwasreplacedbytwointerfaces:IHtttpControllerActivatorandIHttpControllerSelector.
UnfortunatelyDefaultHttpControllerSelectorstilldoesn'tsupportAreasbydefault.TosupportityouhavetowriteyourHttpControllerSelectorfromscratch.Tobehonest,IwillderivemyselectorfromDefaultHttpControllerSelector.
InthispostIwillshowyouhowyoucandoit.
IntheconstructormentionedaboveIcalledthebaseconstructorandstoredtheHttpConfiguration.Wewilluseitalittlebitlater.
Mycodewillusetwoconstants:
Youcanunderstandwhyweneedfirstonebyname.ThesecondonecontainsthenameofthevariablewhichwewillusetospecifyareanameinRoutescollection.
SomewherewehavetostorealloftheAPIcontrollers.
MethodGetControllerTypestakesalltheAPIcontrollerstypesfromallofyourassemblies,andstoreitinsidethedictionary,wherethekeyisFullNameofthetypeandvalueisthetypeitself.
Ofcoursewewillsetthisdictionaryonlyonce.Andthenjustuseit.
Nowwearereadytoimplementoneoftheimportantmethod:
InthatmethodItrytotaketheHttpControllerDescriptorfrommethodGetApiControllerandifitreturnnullthencallthebasemethod.
Andadditionalmethods:
?
MethodGetAreaNamejusttakesareanamefromHttpRequestMessage.
MethodGetControllerTypeByAreaaretriestofindthecontrollerintheApiControllerTypesbyfullnameofthecontrollerwherethefullnamecontainsarea'snamesurroundedby"."(e.g.".Admin.")andendswithcontrollername+controllersuffix(e.g.UsersController).
AndifacontrollertypefoundthenmethodGetApiControllerwillcreateandreturnbackHttpControllerDescriptor.
So,myAreaHttpControllerSelectorisreadytoberegisteredinmyapplication.
?
That'sall.
YouhavetoaddnewHttpRoutetoyourAreaRegistration.csfile:
?
OrjustuseoneglobalrouteinyourGlobal.asaxlike:
?
HttpControllerFactorywasdeletedinASP.NETMVC4RC.Actually,itwasreplacedbytwointerfaces:IHtttpControllerActivatorandIHttpControllerSelector.
UnfortunatelyDefaultHttpControllerSelectorstilldoesn'tsupportAreasbydefault.TosupportityouhavetowriteyourHttpControllerSelectorfromscratch.Tobehonest,IwillderivemyselectorfromDefaultHttpControllerSelector.
InthispostIwillshowyouhowyoucandoit.
AreaHttpControllerSelector
Firstofall,youhavetoderiveyourclassfromDefaultHttpControllerSelectorclass:publicclassAreaHttpControllerSelector:DefaultHttpControllerSelector { privatereadonlyHttpConfiguration_configuration; publicAreaHttpControllerSelector(HttpConfigurationconfiguration) :base(configuration) { _configuration=configuration; } }
IntheconstructormentionedaboveIcalledthebaseconstructorandstoredtheHttpConfiguration.Wewilluseitalittlebitlater.
Mycodewillusetwoconstants:
privateconststringControllerSuffix="Controller"; privateconststringAreaRouteVariableName="area";
Youcanunderstandwhyweneedfirstonebyname.ThesecondonecontainsthenameofthevariablewhichwewillusetospecifyareanameinRoutescollection.
SomewherewehavetostorealloftheAPIcontrollers.
privateDictionary<string,Type>_apiControllerTypes; privateDictionary<string,Type>ApiControllerTypes { get{return_apiControllerTypes??(_apiControllerTypes=GetControllerTypes());} } privatestaticDictionary<string,Type>GetControllerTypes() { varassemblies=AppDomain.CurrentDomain.GetAssemblies(); vartypes=assemblies.SelectMany(a=>a.GetTypes().Where(t=>!t.IsAbstract&&t.Name.EndsWith(ControllerSuffix)&&typeof(IHttpController).IsAssignableFrom(t))) .ToDictionary(t=>t.FullName,t=>t); returntypes; }
MethodGetControllerTypestakesalltheAPIcontrollerstypesfromallofyourassemblies,andstoreitinsidethedictionary,wherethekeyisFullNameofthetypeandvalueisthetypeitself.
Ofcoursewewillsetthisdictionaryonlyonce.Andthenjustuseit.
Nowwearereadytoimplementoneoftheimportantmethod:
publicoverrideHttpControllerDescriptorSelectController(HttpRequestMessagerequest) { returnGetApiController(request)??base.SelectController(request); }
InthatmethodItrytotaketheHttpControllerDescriptorfrommethodGetApiControllerandifitreturnnullthencallthebasemethod.
Andadditionalmethods:
MethodGetControllerTypeByAreaaretriestofindthecontrollerintheApiControllerTypesbyfullnameofthecontrollerwherethefullnamecontainsarea'snamesurroundedby"."(e.g.".Admin.")andendswithcontrollername+controllersuffix(e.g.UsersController).
AndifacontrollertypefoundthenmethodGetApiControllerwillcreateandreturnbackHttpControllerDescriptor.
So,myAreaHttpControllerSelectorisreadytoberegisteredinmyapplication.
RegisteringAreaHttpControllerSelector
ThenextthingyouhavetodoistosaytoyourapplicationtousethiscontrollerselectorinsteadofDefaultHttpControllerSelector.Andfortunatelyitisreallyeasy-justaddoneadditionallinetotheendofApplication_StartmethodinGlogal.asaxfile:UsingAreaHttpControllerSelector
Ifyoudideverythingright,nowyoucanforgetaboutthat"nightmare"codementionedabove.Andjuststarttouseit!YouhavetoaddnewHttpRoutetoyourAreaRegistration.csfile:
相关文章推荐
- 【PHP开发】用curl向https发请求时的35号错误
- iOS开发工具-网络封包分析工具Charles
- Tao-ReviewBoard 提交时报出 HttpClient.excuteMethod Error HttpCode=400 的错误
- Flex中使用HTTPService向后发送请求,参数中如何使用URL的保留字符(问号、百分号)
- 网络子系统81_inet协议族-SOCK_RAW(二)
- 计算机网络基础_2_网络层的作用(上) --IP地址、子网掩码和路由器的作用
- 网络子系统80_inet协议族-SOCK_RAW(一)
- Linux网络编程一步一步学-编写一个HTTP协议的目录
- 让HTTP萌娘帮你记住状态码吧
- 网络传输时,Java中byte[]转String问题
- 关于安卓HTTP请求用HttpUrlConnection仍是HttpClient好
- axis2处理http 307问题
- Android 网络编程 Socket Http
- linux C发送 http 请求
- HttpApplication整体请求图
- 网络编程--IO模型示例
- Restful是一种非常优美的http接口设计风格及设计规范
- 基于IPv6的下一代网络技术的特征分析
- Win7+VMware Workstation环境下的CentOS-Linux网络连接设置
- Android联网使用HttpClient 和HttpResponse 小结