Monday, April 30, 2012

Using WCF Data Services Tutorial - Part 1

With the recent release of WCF Data Services 5.0 a few weeks ago, I thought it would be a good idea to introduce the technology to those of you that have not seen it before. 

WCF Data Services for those of you used to creating traditional SOAP based or REST services using WCF has a different purpose and use. It builds upon the Open Data Protocol (OData) that Microsoft created to expose data as resources that are addressable by URIs. OData builds upon the AtomPub protocol to represent data in a standardized method and then makes it accessible via HTTP. Through REST based services you can access any type of data using the standard HTTP verbs (GET, POST, PUT, DELETE).

These services offer a powerful way to quickly expose your data as services without a lot of the manual work involved otherwise. In addition the services are customizable via service operations and interceptors. The OData protocol is something not confined to .NET either. The idea is an open protocol for exposing your data in a platform agnostic manner via HTTP. There are a slew of .NET OData client libraries that sit atop of data services for accessing the data, and there are even libraries in other languages like Java and its OData4J library.

So why is this good? Well 1st off we are exposing data using a known and standardized protocol in OData. Think of the alternative using a traditional WCF service with a webHttpBinding to create a RESTful service. You would be creating from scratch how your data is being exposed and only you and your clients understand this model; it is not a standard. If you being on new clients to consume your services, you have to explain (typically through documentation) on how your data looks when exposed. This is obviously not as easy as telling clients that your services expose data that is built upon the AtomPub format in OData which is a standard. The other main attraction of data services is how much custom and manual plumbing work that gets cut out and streamlines. As you will see below, in just minutes I can have my relational data exposed and accessible via HTTP in a RESTful manner via URIs mapped to my entities.

In my example I am going to expose some relational data via WCF Data Services from the 'AdventureWorks' database on my local SQL Server instance. I just want you to get up and running to see the possibilities, so we will go through all the steps to preform a simple GET on some of the entities we will expose.

First let's start off by creating an Entity Framework model for the  AdventureWorks database. If you want to follow along and do not have the Adventureworks database you can download it from CodePlex here: (http://msftdbprodsamples.codeplex.com/). Begin by going to 'Add -> New Item' and under the 'Data' category on the left select 'ADO.NET Entity Data Model'.


For this example I am using the AdventureWorks database, so I select 'Generate from database' and then navigate through the wizard to set up a connection, naming conventions (I use the default values for this example), and then I selected all the tables before completing the Entity Framework Model.


Now that our EF model is created, we can create our WCF Data Service. I have the new WCF Data Services 5.0 installed which is built upon the OData v3.0 specification, and you can download it from here as well: http://www.microsoft.com/en-us/download/details.aspx?id=29306 In Solution Explorer on your project, select 'Add -> New Item' and under the 'Web' category on the left select 'WCF Data Service (for OData v3)', or similar option if you have an older version of WCF Data Services installed.




This will create a new WCF Data Service with it's default class and 'InitializeService' method. On this class we must Implement the Entity Framework model we created earlier. The default line below instructs you to do so:
public class WcfDataService1 : DataService< /* TODO: put your data source class name here */ >
For this example let's Implement the 'AdventureWorksEntities' class we created earlier like below:
public class WcfDataService1 : DataService<AdventureWorksEntities>
The next step requires us to be explicit on which entities we want to expose and with what level of permissions too. Just to give you a feel of what the exposed data representation looks like in the browser, lets go ahead and expose all entities using the asterisk with 'AllRead' permission:
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
Before viewing the data in the browser, I recommend selecting the browser for VS.NET to use to Google Chrome instead of IE. IE9 at least does not display AtomPub data properly (See UPDATE at the end of this post for using IE), and upon doing a GET on the entities you not be able to view the data. To do this, right-click the WCF Data Service item in Solution Explorer and select: 'Browse With...' as shown below. Select 'Google Chrome' and the browser will display all of the entities that have been exposed. You can also permanently switch the default browser used in this dialog as well by pressing 'Set as Default'







As you see above, all of the 'Collections' from our EF model are exposed. Let's go ahead and only expose the 'Employees' entity by modifying the code to look as follows:
//Only allow the Employees entity collection to be exposed:
config.SetEntitySetAccessRule("Employees", EntitySetRights.AllRead);

//
Now when run in the browser we see only the Employees collection is exposed. Let's explore and expose what information we can get back on this collection by modifying the URI. If I want to get back the Employee with ID '1', I can simply request this using the URI below:



Upon making the GET request, you can see that I get back all of the information just for the Employee with the ID of '1'. 


One other nice feature is the ability to query the entity with some predetermined query string options. For example, when we did a GET for the Employee with an ID=1, you could see there were some related entities 'Employee1' and 'Employee2'. If we use the 'expand' query string option, we can expand on this employee to see related entity information. Modifying the URI to be as follows to expand on the 'Employee1' many to many relationship:



Upon making the GET request with the expand query option you will see the additional related entity information. Try the same procedure for expanding on 'Employee2' to see additional related entity information.

So look at this - in just a few minutes we are up and running by exposing our relational data accessible via HTTP in a RESTful manner using a know open protocol. Pretty cool if you ask me, and even better - really useful. This has just barely scraped the surface of what can be done with WCF Data Services. In the future I will expand on this tutorial getting a little more in depth with some of the additional functionality offered.

UPDATE: To get IE to format the OData as XML, do the following:
  • Tools -> Internet Options
  • Select the Content Tab
  • Under 'Feeds and Web Slices', select 'Settings'
  • Under the 'Advance' section deselect 'Turn on Feed reading view'

6 comments:

  1. Mr Conway where is the part 2 of this series? I can't seem to find it. Thanks.

    ReplyDelete
  2. how do you do WCF Data Services with SSL? will basicHttpBinding work just fine or do I need to change it? In your "Creating a WCF RESTful Service and Secure It Using HTTPS Over SSL" article, it used an interface as the service contract. Since WCF Data Services does not actually need the interface especially in this sample where you only exposed the entities, do you need to add any configuration changes to your web.config or any authentication code lines in your web or application project?

    ReplyDelete
  3. I need to upload mp3 files to my server using WCF RESTful Service.please ,can you help me...urgent....

    ReplyDelete
  4. @Rajesh - I typically use SOAP services for streaming file uploads as opposed to REST based services. I have not done my own REST based upload API. However, it is possible and might be the way to go next time I have to do this.

    Basically the content-type becomes 'multipart/form-data' and you accept a stream of data in the body of the request. This will help and is a simple example: http://blogs.msdn.com/b/henrikn/archive/2012/03/01/file-upload-and-asp-net-web-api.aspx

    ReplyDelete
  5. Hi, nice WCF Data Services Tutorial.Thanks for your help..

    -Aparna
    Theosoft

    ReplyDelete
  6. Where the hell is part 2 ?

    ReplyDelete