您的位置:首页 > 理论基础 > 计算机网络

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.

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:

?
MethodGetAreaNamejusttakesareanamefromHttpRequestMessage.

MethodGetControllerTypeByAreaaretriestofindthecontrollerintheApiControllerTypesbyfullnameofthecontrollerwherethefullnamecontainsarea'snamesurroundedby"."(e.g.".Admin.")andendswithcontrollername+controllersuffix(e.g.UsersController).

AndifacontrollertypefoundthenmethodGetApiControllerwillcreateandreturnbackHttpControllerDescriptor.

So,myAreaHttpControllerSelectorisreadytoberegisteredinmyapplication.

RegisteringAreaHttpControllerSelector

ThenextthingyouhavetodoistosaytoyourapplicationtousethiscontrollerselectorinsteadofDefaultHttpControllerSelector.Andfortunatelyitisreallyeasy-justaddoneadditionallinetotheendofApplication_StartmethodinGlogal.asaxfile:

?
That'sall.

UsingAreaHttpControllerSelector

Ifyoudideverythingright,nowyoucanforgetaboutthat"nightmare"codementionedabove.Andjuststarttouseit!

YouhavetoaddnewHttpRoutetoyourAreaRegistration.csfile:

?
OrjustuseoneglobalrouteinyourGlobal.asaxlike:

?


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: