Creating a Restful WCF service in .NET is pretty easy (once you’ve sorted through the myriad of confusing VS2010 options).
Here’s one way simple way to do it.
Step 1: Create a new plain old C# library.
Fire up Visual Studios 2010, create a blank solution, and add a plain old C# library called ‘Services’.
Step 2: Define your Restful service and Dto.
To create a Restful WCF service that handles a GET request, define the following interface and implementation.
IInvoiceService.cs
using System.ServiceModel; using System.ServiceModel.Web; namespace Services { [ServiceContract] public interface IInvoiceService { [WebGet(UriTemplate = "/invoices")] [OperationContract] InvoiceDto[] GetAllInvoices(); } }
InvoiceService.cs
namespace Services { public class InvoiceService : IInvoiceService { public InvoiceDto[] GetAllInvoices() { return new[] { new InvoiceDto(1, "receiver1"), new InvoiceDto(2, "receiver2") }; } } }
To import these attributes you’ll need to add references to System.ServiceModel and System.ServiceModel.Web
Then add your Dto. Dto’s need to be marked up with DataContract and DataMember attributes so they can be serialized by WCF.
InvoiceDto.cs
using System.Runtime.Serialization; namespace Services { [DataContract(Namespace = "")] public class InvoiceDto { public InvoiceDto(int id, string receiver) { Id = id; Receiver = receiver; } [DataMember] public int Id { get; set; } [DataMember] public string Receiver { get; set; } } }
Step 3: Host it.
There’s lots of ways to host a WCF restful service. We could create a console application and host it there. We could create a new full on ASP.NET website (WCF enabled) and host it there.
But for simplicity (and because this is how we are trying it in our project) create a ‘WCF Service Application’ and host it there in a project call ‘Host’.
Our new Host project comes with a svc file. This file just sits in the IIS (or Cassini) virtual directory and points to the service it supports. You have one svc file per service.
In our case, we don’t need the default Service1 that came with the application (so go ahead and delete those).
Instead, edit the Service1.svc file and point it too the service we just created in our plain old C# library.
Service.svc
<%@ ServiceHost Service="Services.InvoiceService" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
This WebServiceHostFactory is a new class introduced in WCF 3.5 purely for making WCF services restful. By using it, we don’t need any WCF configuration in our webconfig file.
In fact for the purpose of this demo we can completely gut it and leave it empty as shown below.
Host/web.config
<?xml version="1.0"?> <configuration> </configuration>
Step 4: Test it in the browser.
Now if everything is working, we should be able to right click on Service1.svc in our hosted project and go ‘View in browser.
This will fire up Cassini and display a blank page with the message ‘End point not found’. That’s OK.
The real test for us is when we add on the restful GET extension ‘/invoices’ to the URL. When we do that, we should get something like this:
http://localhost:49619/Service1.svc/invoices
Something to be aware of …
Now if you like WCF, and are thinking of building your next application using Restful WCF service, beware of one big gotcha.
You can’t autogenerate client side proxies using WCF.
Rest (HTTP) doesn’t knew anything about WSDL (the SOAP contract used by Visual Studios to create the proxies).
It can’t automatically create proxies for you like regular WCF. This might change in future versions of WCF (which Microsoft has indicated are going to be way more Restful). But for for now, to call this service from a unit test, you have to hand role your own proxy, or just work with basic .NET Http constructs like WebHttpRequest and WebHttpResponse as shown below.
using System.Net; using NUnit.Framework; namespace Test { [TestFixture] public class When_calling_a_restful_service { [Test] public void Should_get_proper_HTTP_codes_and_headers() { var url = "http://localhost:49619/Service1.svc/invoices"; var request = (HttpWebRequest)WebRequest.Create(url); var response = (HttpWebResponse)request.GetResponse(); Assert.AreEqual(200, (int)response.StatusCode); } } }
This isn’t the end of the world. On one hand your proxies are always up to sync (because there are none). On the other you just need to track URLs and figure out how to tell your client where your services live.
These are some of the things we’re learning as we spike out some Silverlight Rstful implementation stuff with WCF. Would love to hear about any more insights or gotchas as we definitely haven’t figured it all out.
Sean Feldman
Dec 31, 2010 @ 02:16:13
Good write Jonathan.
JR
Dec 31, 2010 @ 18:22:31
Thx Sean. Couldn’t find a simple example I liked so I created this one.
Cheers – JR
sameer
Jun 07, 2011 @ 16:28:35
I tried this but I am getting bad request 400 error.
I followed exactly what you mentioned here.
thanks
Sameer K
sameer
Jun 07, 2011 @ 17:55:35
I was able to make it work. There is a web.config value to be implemented.
It has to modify the binding property to “webHttpBinding” and the endpoint behaviour should be webhttp
ex:
Dennis
Jan 10, 2012 @ 15:48:42
Am I missing something? When I right click and select View in Browser I get an error: Endpoint not found. Any idea?
Mohak Mahato
Jul 24, 2011 @ 18:30:20
Hi JR,
I am new to restful websevice,It might be an odd question.Is it possible to get the returned XML String from the response object?
Thanks
Mohak
JR
Jul 28, 2011 @ 02:51:53
Hi Mohak,
I am pretty sure you can. Try the above example and see the the response returns you. Most likely it will be XML. But you can also return JSON. It all depends on how your service is configured.
Cheers – JR
An Introduction to RESTful WCF services « Abhijit's World
Jan 07, 2012 @ 10:32:38
raja
Mar 05, 2012 @ 07:04:52
Good Article.
Raj
May 18, 2012 @ 14:01:58
Is there a way to remove .svc extention from URI? Like
http://localhost:49619/Service1/invoices
anil
Jul 24, 2012 @ 09:44:27
How to create WCFREST service in .net perform all CRUD operations in database and also consume this service ASP.NET webpages
pls help me
build-iphone-apps - Cost of Iphone 4s - build-iphone-apps
Sep 02, 2012 @ 21:31:51
Saif Khan
Oct 06, 2012 @ 07:33:03
A very nice article. But I have a question though; does it mean that i have to have my service in a running state in order to unit test it. Is there no way where I can mock webhttprequest and can just test my web service logic without having it in running state.
JR
Oct 06, 2012 @ 13:07:41
Hi Saif,
You can mock WCF services but I would recommend doing it with something like Moq.
If you want to test the configure of the service you can dynamically spin the service up on another port and hit it.
Cheers – Jonathan
anil
Oct 08, 2012 @ 04:56:18
Thank you,
Can you give me example on perform all DML operations in REST service and also How to consume this service in my asp.Net website Perform all operations
Plz help me I AM NEW this one
Rajiv Kulkarni
Apr 22, 2013 @ 12:29:54
How do you install the service? Thanks.
Dave
May 30, 2014 @ 11:16:08
What does this bit mean, it’s not 100% clear.
In our case, we don’t need the default Service1 that came with the application (so go ahead and delete those).
Instead, edit the Service1.svc file and point it too the service we just created in our plain old C# library.
I have two files; IService1 and Service.svc in the host, do I delete these? Not really sure as the second paragraph tells me to edit the .svc.
WCF with no service xml or endpoints? What is this magic? | Hosk's Dynamic CRM Blog
Sep 15, 2014 @ 09:32:44