您的位置:首页 > 其它

RESTful WCF Services with No svc file and No config and How to use Service Route

2012-11-14 14:30 651 查看
RESTfulWCFServiceswithNosvcfileandNoconfig

WhileMicrosoftcontinuestoaddfeaturestoWCFwitheachversion,theyarealsoaddingfeaturesthatsimplifyworkingwithWCFservicesaswell.HistoricallyWCFhasbeensomewhatintimidatingtotheuninitiatedbecauseofthenon-trivialconfigurationforendpointsincludingbehaviors,bindings,andmuchmore.Forthisreason,alotofpeoplestayedwith“oldschool”asmxwebservices.WiththenewfeaturesofWCF4,youcanbuildpowerfulwebserviceswith*no*svcfileand*no*endpointconfiguration.

BuildingaRESTfulWCFserviceinthiswayisquiteeasyandyoudon’tneedrelyonanyitemtemplates.Juststartwithablankasp.netwebapplicationprojectinVisualStudio.Theweb.configfileisvirtuallyempty:

<configuration>

[code]<system.web>
<compilationdebug="true"targetFramework="4.0"/>

</system.web>

</configuration>

[/code]
NextjustaddaregularC#class-forthisexample,IcallminePersonServiceanditwillhavebasicCRUDoperations.TypicallywecreateinterfacesinWCFtodefineourServiceContractandoperationslikethis:

[ServiceContract]

[code]interfaceIPersonService
{

[OperationContract]

PersonGetPerson(stringid);


[OperationContract]

PersonInsertPerson(Personperson);


[OperationContract]

PersonUpdatePerson(stringid,Personperson);


[OperationContract]

voidDeletePerson(stringid);

}

[/code]
Keepinmind,thisstepis*not*required.You*could*decorateyourserviceclassdirectlywiththeseattributesandnotevenhavetheinterfaceatall.However,inthiscase,it’saniceconveniencetoencapsulatealltheWCFattributesontheinterfaceratherthanyourimplementationclass.TheimplementationofourPersonServiceclasslookslikethis(I’veremovedthecodethataccessthedatastoreforbrevity):


[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]

[code]publicclassPersonService:IPersonService
{

[WebGet(UriTemplate="Person({id})")]

publicPersonGetPerson(stringid)

{

}


[WebInvoke(UriTemplate="Person",Method="POST")]

publicPersonInsertPerson(Personperson)

{

}


[WebInvoke(UriTemplate="Person({id})",Method="PUT")]

publicPersonUpdatePerson(stringid,Personperson)

{

}


[WebInvoke(UriTemplate="Person({id})",Method="DELETE")]

publicvoidDeletePerson(stringid)

{

}

}

[/code]
ThisisjustanormalC#classthatimplementaninterface.It’salsodecoratedwiththetypicalWebGet/WebInvokeattributes(intheSystem.ServiceModel.Webnamespace)thatweuseforRESTfulservices.Alsonoticethat3ofthe4methodshavethesameUriTemplatebuttheyaredifferentiatedbytheHTTPmethod(i.e.,GET/PUT/DELETE).AlsonoticetheAspNetCompatibilityRequirementsattribute–thisisneededforRESTfulservicesthatareprocessedintheASP.NETpipelineasdescribedhere.Youalsohavetoaddthistotheconfigfile(Iknow,Iknow–Isaid“noconfig”butImeant“nouglyWCFendpointconfig”!):

<system.serviceModel>

[code]<serviceHostingEnvironmentaspNetCompatibilityEnabled="true"/>
</system.serviceModel>

[/code]
SohowdowetakethisregularC#classandmakeitintoaservicewithoutan*.svcfile?TheSystem.Web.RoutinginfrastructurehasnowbeenincorporatedintoWCF4tomakethispossible.Justaddthelineofcode(line#5)toyourglobal.asax:


publicclassGlobal:System.Web.HttpApplication

[code]{
protectedvoidApplication_Start(objectsender,EventArgse)

{

RouteTable.Routes.Add(newServiceRoute("",newWebServiceHostFactory(),typeof(PersonService)));

}

}

[/code]
TheWebServiceHostFactorymakesRESTfulservicespossibleinWCF.ThefirstparameterofmyServiceRouteconstructorisanemptystringwhichmeansthatmyURIofmyservicewillhangrightoffoftheroot–thisgetcombinedwiththeUriTemplatedefinedintheWebGet/WebInvokeattributes.Sotogetapersonfrommyservice,aURIwouldlooklikethis:http://mydomain.com/Person(21).IfIhadspecified“foo”insteadofanemptystringinthefirstparametersoftheServiceRouteconstructor,thenmyURIwouldlooklikethis:http://mydomain.cmo/foo/Person(21).

That’sit!YounowhaveafullyfunctioningRESTfulWCFservicethatyoucanfullytestwithFidderforallHTTPverbs.

OneinterestingaspecttoallthisisthatyoucandoallthisinMVCaswell.Infact,ItypicallydouseMVCtoreturnJSONtoviewsforAJAXcallsinmyMVCapps.However,ifyouwerebuildingstand-aloneservicesforthis,wouldMVCbeeasierthantheexampleofabove?Keepinmind,wecouldsimplifytheexampleaboveevenfurtherbyeliminatingtheIPersonServiceinterfacealltogether.IdaresaythatsettingupRESTfulroutesliketheonesshownaboveiseasierwithWCFthanMVC(this,comingfroman“MVCguy”)becausewecanapplytheUriTemplatesdirectlytothemethods.ToaccomplishthesameinMVC,youhavetocreatecustomrouteconstraintstoavoidthenameoftheC#methodsfromshowingupintheURL(andhonoringtheRESTHTTPverbs).Ifyouaregoingtodothis,Ireallyliketheapproachshownhere.It’sacoolapproach,butit’s*more*workthanjustdoingitwithRESTfulWCF–nosvcfileandnoconfiguration.

Infact,usingtheWCFinfrastructuregetsyouevenmorefeaturesforfree.Forexample,ifweadd1morelineofconfiguration(checkoutline#5below)wegetahelppageandautomaticformatselectionforfree!Nowourentireconfigurationjustlookslikethis(andstillnoWCFendpointconfigurationneeded):

<system.serviceModel>

[code]<serviceHostingEnvironmentaspNetCompatibilityEnabled="true"/>
<standardEndpoints>

<webHttpEndpoint>

<standardEndpointname=""helpEnabled="true"automaticFormatSelectionEnabled="true"/>

</webHttpEndpoint>

</standardEndpoints>

</system.serviceModel>

[/code]
Noticeallwehadtodotogetthehelppagewastherequest“/help”:



TheautomaticformatselectioninWCFwillhonortheAcceptheaderand/ortheContent-typeheaderandreturnXML,JSON,etc.tothecallerbasedonthevaluespecifiedintheheader.Again,thattakescustomcodeinMVCwhichyougetforfreeinWCF.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: