Restful WCF services with no SVC file and no config
While Microsoft continues to add features to WCF with each version, they are also adding features thatSimplifyWorking with WCF services as well. historically WCF has been somewhat intimidating to the uninitiated because of the non-trivial configuration for endpoints including behaviors, bindings, and much more. for this reason, a lot of people stayed with "Old School" asmx Web Services. with the new features of WCF 4, you can build powerful web services with * No * SVC file and * No * endpoint configuration.
Building a restful WCF Service in this way is quite easy and you don't need rely on any item templates. just start with a blank Asp.net web application project in Visual Studio. the web. config file is always Ally empty:
1:<Configuration>
2:<System. Web>
3:<Compilation Debug= "True" Targetframework= "4.0" />
4:</System. Web>
5:</Configuration>
Next just add a regular C # class-for this example, I call mine personservice and it will have basic CRUD operations. Typically we create interfaces in WCF to define our servicecontract and operations like this:
1:[Servicecontract]
2:InterfaceIpersonservice
3:{
4:[Operationcontract]
5:Person getperson (StringID );
6:
7:[Operationcontract]
8:Person insertperson (person );
9:
10:[Operationcontract]
11:Person updateperson (StringID, person );
12:
13:[Operationcontract]
14:VoidDeleteperson (StringID );
15:}
Keep in mind, this step is ** not * required. you * cocould * decorate your service class directly with these attributes and not even have the interface at all. however, in this case, it's a nice convenience to encapsulate all the WCF attributes on the Interface rather than your implementation class. the implementation of our personservice class looks like this (I 've removed the code that access the data store for breech ):
1:[Aspnetcompatibilityrequirements (requirementsmode = aspnetcompatibilityrequirementsmode. Allowed)]
2:Public ClassPersonservice: ipersonservice
3:{
4:[Webget (uritemplate ="Person ({ID })")]
5:PublicPerson getperson (StringID)
6:{
7:}
8:
9:[Webinvoke (uritemplate ="Person", Method ="Post")]
10:PublicPerson insertperson (person)
11:{
12:}
13:
14:[Webinvoke (uritemplate ="Person ({ID })", Method ="Put")]
15:PublicPerson updateperson (StringID, person)
16:{
17:}
18:
19:[Webinvoke (uritemplate ="Person ({ID })", Method ="Delete")]
20:Public VoidDeleteperson (StringID)
21:{
22:}
23:}
This is just a normal C # class that implement an interface. it's also decorated with the typical webget/webinvoke attributes (in the system. servicemodel. web namespace) that we use for restful services. also notice that 3 of the 4 methods have the same uritemplate but they are differentiated by the HTTP method (I. E ., GET/Put/delete ). also notice the aspnetcompatibilityrequirements Attribute-this I S needed for restful services that are processed in the ASP. net pipeline asdescribed here. you also have to add this to the config file (I know, I know-I said "no config" but I meant "no uugly WCF endpoint config "!) :
1:<System. servicemodel>
2:<Servicehostingenvironment Aspnetcompatibilityenabled= "True"/>
3:</System. servicemodel>
So how do we take this regular C # class and make it into a service without an *. SVC file? The system. Web. Routing infrastructure has now been inmo-ated into WCF 4 to make this possible. Just add the line of code (line #5) to your global. asax:
1:Public ClassGlobal: system. Web. httpapplication
2:{
3:Protected VoidApplication_start (ObjectSender, eventargs E)
4:{
5:Routetable. routes. Add (NewServiceroute ("",NewWebservicehostfactory (),Typeof(Personservice )));
6:}
7:}
The webservicehostfactory makes restful services possible in WCF. the first parameter of my serviceroute constructor is an empty string which means that my URI of my service will hang right off of the root-this get combined with the uritemplate defined in the webget/webinvoke attributes. so to get a person from my service, a URI wowould look like this: http://mydomain.com/Person (21 ). if I had specified "Foo" instead of an empty string in the first parameters of the serviceroute constructor, then my URI wowould look like this: http://mydomain.cmo/foo/Person (21 ).
That's it! You now have a fully functioning restful WCF Service that you can fully test with fidder for all HTTP verbs.
one interesting aspect to all this is that you can do all this in MVC as well. in fact, I typically do use MVC to return JSON to views for Ajax callin my MVC apps. however, if you were building stand-alone services for this, wocould MVC be easier than the example of above? Keep in mind, we cocould simplify the example abve even further by eliminating the ipersonservice interface all together. I daresay that setting up restful routes like the ones shown above is easier with WCF than MVC (this, coming from an "MVC guy") because we can apply the uritemplates directly to the methods. to accomplish the same in MVC, you have to create custom route constraints to avoid the name of the C # methods from showing up in the URL (and honoring the rest HTTP verbs ). if you are going to do this, I really like the approach shown here. it's a cool approach, but it's * more * work than just doing it with restful WCF-No SVC file and no configuration.
In fact, using the WCF infrastructure gets you even more features for free. for example, if we add 1 more line of configuration (check out line #5 below) we get a Help Page and automatic format selection for free! Now our entire configuration just looks like this (and still no WCF endpoint configuration needed ):
1:<System. servicemodel>
2:<Servicehostingenvironment Aspnetcompatibilityenabled= "True"/>
3:<Standardendpoints>
4:<Webhttpendpoint>
5:<Standardendpoint Name= "" Helpenabled= "True" Automaticformatselectionenabled= "True"/>
6:</Webhttpendpoint>
7:</Standardendpoints>
8:</System. servicemodel>
Notice all we had to do to get the help page was the request "/help ":
The automatic IC format Selection in WCF will honor the accept header and/or the Content-Type header and return XML, JSON, etc. to the caller based on the value specified in the header. again, that takes custom code in MVC which you get for free in WCF.