Windows Communication Foundation (WCF) Data Services

WCF Data Services

Introduction

There are many Ajax/RIA/Rich Client/etc. applications, which access data directly from the client. Mashups also combine data that is available on the web mostly in the form of RSS/Atom feeds and present it to the user in the more meaningful way.
Writing an entire web service to expose the data layer over Http requires a significant developer investment. WCF Data Services (originally known as ADO.NET Data Services) is a framework that automatically exposes data in the RESTful manner. It allows AJAX applications, access to the database via Http without writing a web service. It also provides access to data to third parties in a standardized fashion. WCF Data Services Framework exposes data from any Linq enabled data source. In addition, it allows the client to be extremely lightweight, only needing an Http request mechanism and a JSON or Atom parser, as opposed to a whole data access stack.

Creating a Windows Communication Foundation (WCF) Data Service

I have created a simple SQL Server database that contains the below three tables and a stored procedure, namely GetAvailableProducts. For simplicity, there will a one order for each product ordered. We will create a WCF Data Service that will expose this data via Http.



Figure 1

Create a new ASP.NET Web Application and name it as AdoNetDataServicesDemo.

Add an ADO.NET Entity Data Model to the Project. Let’s name it as CustomerOrdersModel. Once you click on OK button, it will start the Entity Data Model wizard. Follow the wizard to generate the Entity Model from the database. Provide the database connection information and choose the above tables and stored procedure in the database objects list. After you click on the Finish button, Entity Data Model will be generated and added to the project as shown below:



Figure 2

Now add an ADO.NET Data Service to the project and name it as CustomerOrders. CustomerOrders.svc and CustomerOrders.svc.cs files will be generated and added to the project. In CustomerOrders.svc.cs files there will be an auto-generated class, namely CustomerOrders. This class inherits from DataService class. Specify the generic parameter as CustomerOrdersC, which is the data context class generated by the Entity data Model.

Add the below new method to this class to expose the data returned by stored procedure as an IQueryable property.


[WebGet]        
public IQueryable<Products> ProductList()        
{    
return new CustomerOrdersC().GetAvailableProducts().AsQueryable<Products>();
}
By default no entity or operation is made visible/updatable/etc. Add the below lines in the InitializeService method to make all the entities and operations visible/updatable/etc.
public static void InitializeService(IDataServiceConfiguration config)        
{
config.SetEntitySetAccessRule(“*”, EntitySetRights.All);
config.SetServiceOperationAccessRule(“ProductList”, ServiceOperationRights.All);
}

We have given all the permissions to all the entities/operations above but we can control that at more granular level, if required.

Now press F5 to launch the WCF Data Service and type the below URIs in the address bar and observe the data displayed in the browser.


http://localhost:1371/CustomerOrders.svc/ProductList
http://localhost:1371/CustomerOrders.svc/Customers?$top=1

There are different options available that we can be used to filter/sort the data. Below are the options that we can use in the URIs.



Figure 3

In the filter expression we can use the below operators.


Figure 4

Consuming the Windows Communication Foundation (WCF) Data Service

Add a Windows Forms Application to the solution and name it as DemoClient.

Open the Add Service Reference dialog box and discover/add CustomerOrder.svc service reference to the project. Alternatively you can also use the DataServiceUtil.exe to generate the client-side classes.

Change the default Form so that it looks like below.



Figure 5

Double click on the View Orders button to open the Click event handler and write the below code in it.


private void ViewOrdersButton_Click(object sender, EventArgs e)        
{            
CustomerOrdersC svcContext = new CustomerOrdersC(new Uri(“http://localhost:1371/CustomerOrders.svc/”));            
int id = Convert.ToInt32(CustomerId.Text.Trim());            
var customer = svcContext.Customers.Where(c => c.CustomerId == id).FirstOrDefault();
CustomerName.Text = customer.LastName + “, ” + customer.FirstName;          
var orders = svcContext.Orders.Expand(“Products”)                                        
.Where(o => o.Customers.CustomerId == id)                                        
.ToList();             
OrderGridView.DataSource = orders.Select(o => new                                            
{Id = o.OrderId,                                                
Product = o.Products.ProductName,                                                
Quantity = o.Quantity}).ToList();
}

In the above event handler we created an instance of CustomerOrdersC auto-generated class, and queried the customer details based on the Id entered by the user on the UI. Then we pulled the orders of that customer with the product details. Then we showed the data on the UI, returned by the WCF Data Service. WCF Data Service doesn’t support Joins; we need to use Expand extension method to get the data in the related tables, as shown above.

In the Click event handler of Add New button, write the below code.


private void NewProductButton_Click(object sender, EventArgs e)        
{
CustomerOrdersC svcContext = new CustomerOrdersC(new Uri(“http://localhost:1371/CustomerOrders.svc/”))            
svcContext.AddToProducts(                
new Products()                 
{ProductName = ProductName.Text.Trim()});
           svcContext.SaveChanges();
}
In the above event handler we create a new Product and saved it in the database. Finally in the Click event handler of View Products button, write the below code.
private void ViewProductsButton_Click(object sender, EventArgs e)        
{
CustomerOrdersC svcContext = new CustomerOrdersC(new Uri(“http://localhost:1371/CustomerOrders.svc/”));
           ProductsGridView.DataSource = svcContext.Products.ToList<Products>();        
}

In the above event handler we simply query all the records in the Products table and display them on the UI.

Now set the DemoClient as the default project and press F5 to launch it. Type 1 in the Customer Id textbox and click the View Orders button to see all the orders of the customer.

Click on the View Products button and all the products will be shown on the screen as can be seen in the below screen shot.



Figure 6

Now type Printers in the Product Name textbox and click on Add New button. In addition, click on the View Products button to see the updated list of products in the database. You will see a new row has been added for the Printers at the bottom of the Products table as shown below.



Figure 7

If you see under the covers, all the Linq queries are converted to WCF Data Services URI, which are used to retrieve/update the data in the database. In fact, we can directly use that URI in the client application. In that case we don’t even need to add the service reference. We just have to create the instance of DataServiceContext class, which is the base class of CustomerOrdersC class in the above example and pass the URI to its Execute method.

We have successfully created a WCF Data Service and consumed the same in Windows Forms application. WCF Data Service Framework made it possible to get the data service up and running in just few minutes.

Happy Coding!
Sajad Deyargaroo

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read