Thursday, June 14, 2012

Creating and Consuming WCF Data Service

WCF Data Services provides the ability to create Windows Communication Foundation (WCF) services that use the Atom Publishing protocol (AtomPub) and Open Data protocol (OData) to expose and consume data over the web. OData is an open protocol for sharing data that builds on Atom Publishing protocol
(AtomPub).
In this post I will explain you how to use a WCF Data Service. Create a new web application and add a WCF Data Service template from the Add New Item Dialogue box. We named it gamesDataService, this service will give us the detail of games. The gamesDataService contains the following code:
namespace wcfDataService  
 {  
   public class gamesDataService : DataService< /* TODO: put your data source class name here */ >  
   {  
     // This method is called only once to initialize service-wide policies.  
     public static void InitializeService(DataServiceConfiguration config)  
     {  
       // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.  
       // Examples:  
       // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);  
       // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);  
       config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;  
     }  
   }  
 }  
The code-behind class inherits from the generic DataService class. A comment appears where the parameter type is expected, gamesDataService in this case. The code contains a method InitializeService which accepts one parameter of type DataServiceConfiguration. This method is used to set up service configuration. The DataServiceConfiguration class has a SetEntitySetAccessRule method that accepts two parameters. The first parameter represents the name of the entity set on which you want to set permission. This parameter also accepts the asterisk (*) wildcard to set permissions on all entity sets. The second parameter is an EntitySetRights enumeration value that represents the permissions you want to assign to the entity set.
Following are the EntitySetRights values:
  1. All -> Provides authorization to create, read, update, and delete data.
  2. AllRead -> Provides authorization to read data.
  3. AllWrite -> Provides authorization to write data.
  4. None -> Denies all rights to access data.
  5. ReadMultiple -> Provides authorization to perform multiple item queries to read from the entity set.
  6. ReadSingle -> Provides authorization to perform single item queries to read from the entity set.
  7. WriteAppend -> Provides authorization to write new items to the entity set.
  8. WriteDelete -> Provides authorization to delete items from the entity set.
  9. WriteMerge -> Provides authorization to perform merge-based updates, in which the payload must be an entity and needs only to contains the properties being modified.
  10. WriteReplace Provides authorization to perform replace-based updates, in which the payload must be an entity and should contains all the properties of the entity.
The config object sets permissions on the operations by providing a ServiceOperationRights enumeration value to the SetServiceOperationAccessRule method. The config.DataServiceBehavior.MaxProtocolVersion is used to gets or sets the maximum protocol version that is supported by the response sent by the data service.
Now we will add a class called Games to our project. In the Games class we create four properties which are shown below:
namespace wcfDataService  
 {  
   [DataServiceKey("gameID")]  
   public class Games  
   {  
     public long gameID { get; set; }  
     public string name { get; set; }  
     public string size { get; set; }  
     public string price { get; set; }  
   }  
 }  
After creating this class we create properties in our gamesDataService class to expose data. This property gets data from a hard-coded list of games but could certainly get its data from a back-end SQL Server or other source. The property’s data type must be of generic IQueryable. The following code shows completed gamesDataService class with Game property
namespace wcfDataService  
 {  
   public class gamesDataService : DataService<gamesDataService>  
   {  
     public IQueryable<Games> Game  
     {  
       get  
       {  
         return (new List<Games>  
         {  
           new Games{ gameID=001, name="Street Fighter", price="10$", size="10MB" },  
           new Games{ gameID=002,name="Need For Speed 2", price="25$", size="250MB" },  
           new Games{ gameID=003, name="Delta Force 1", price="30$", size="300MB" }  
         }).AsQueryable();  
       }  
     }  
     // This method is called only once to initialize service-wide policies.  
     public static void InitializeService(DataServiceConfiguration config)  
     {        
       config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);        
       config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;  
     }  
   }  
 }  
Now view the gamesDataService in browser it will show the following output:

The browser shows an XML representation of the service. In the defined namespaces, the atom namespace is defined. This is the namespace that is used for RSS feeds. The Game collection is defined as a relative URI location, so adding Game to the end of the URI will display an XML feed containing the list of games.
In order to retrieve schema information add /$metadata at the end of the URI.
Now we will create a web form and we will get the data from the gamesDataService and will display it in a gridview. Add a new webform wfGames to the project, then add a gridview named gvGames to it. The aspx code is:
<html xmlns="http://www.w3.org/1999/xhtml">  
 <head runat="server">  
   <title></title>  
 </head>  
 <body>  
   <form id="form1" runat="server">  
   <div>  
     <asp:GridView ID="gvGames" runat="server" ></asp:GridView>  
   </div>  
   </form>  
 </body>  
 </html>  
Before we write code for data binding first add a reference to the WCF service. Right click on the solution and select Add Service Reference, a dailogue window is opened click the Discover button, it will show the gamesDataService, then click the OK button.
Now in the Page Load event add the following code to retrieve data and display it in a grid view:
namespace wcfDataService  
 {  
   public partial class wfGames : System.Web.UI.Page  
   {  
     protected void Page_Load(object sender, EventArgs e)  
     {  
       gamesDataService gds = new gamesDataService();  
       var query = (from f in gds.Game  
              select f).ToList();  
       gvGames.DataSource = query;  
       gvGames.DataBind();  
     }  
   }  
 }  
We create an object of gamesDataService class and then write a simple LINQ query to get all the games and then bind the list with the grid view. The following output is shown in the browser:
Thanks for reading this post, if you like it then share it with others, you can also the download complete source code from below sky drive link
Download WCFDataService Project


References:
Accessing Data with Microsoft.NET Framework 4 Ebook

Friday, June 1, 2012

Calling a WCF Service from Client Side( JavaScript ) ( Ajax Enabled WCF Service )

In this post I will show you how to call the WCF service from the client side. First of all create a new Asp.net empty website. From the add new item dialog box add a new web form. In this web form add two text boxes and a label control. In text boxes we will take the numbers from the user and in label we will show the sum of the numbers, also add a button control. The aspx source code looks like:
<asp:TextBox ID="txtNum1" runat="server" ClientIDMode="Static" />  
 <br />  
 <asp:TextBox ID="txtNum2" runat="server" ClientIDMode="Static" />  
 <br />  
 <input name="ButtonCalculate" type="button" value="Sum"  
 onclick="ButtonCalculate_onclick()" />  
 <br />  
 <asp:Label ID="lblResult" runat="server" ClientIDMode="Static" ></asp:Label>  
Now after  this from the add new item dialogue box add a new Ajax enabled WCF service to your solution. It will add two files one with .svc and one with .cs extension. Now open the .cs file and write a function for calculating the sum of two numbers. The code is below:
[ServiceContract(Namespace = "")]  
 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  
 public class ServiceAddNumbers  
 {       
      [OperationContract]  
      public int AddNumbes(int a,int b)  
      {           
           return a+b;  
      }        
 }  
In the above code namespace attribute is not necessary. We created a function AddNumbers which takes two integers and return its sum.
Now we will look at how to call this service from the client side. First add a script manager to the page. In source of Script Manager add a services tag and inside it add a reference to the wcf service. The code is below:
<asp:ScriptManager ID="ScriptManager1" runat="server">  
 <Services>  
     <asp:ServiceReference Path="~/ServiceAddNumbers.svc" />  
 </Services>  
 </asp:ScriptManager>  
After this we will write a JavaScript function to call the service. The function code is below :
<script language="javascript" type="text/javascript">  
     function ButtonCalculate_onclick() {  
       var svc = new ServiceAddNumbers;  
       svc.AddNumbes(txtNum1.value, txtNum2.value, onSuccess, onFail, null);  
       function onSuccess(result) {         
         lblResult.innerText = result;  
       }  
       function onFail(result) {  
         alert(result);  
       }            
 }  
   </script>  
The svc.AddNumbers function took five parameters first and second are the numbers, onSuccess function is called on successfully calling the service and onFail if an error occured and last parameter is usercontext set it to null.
Now the code is completed. Just run it add two numbers and it will show the sum of two numbers in the label control.

Download the complete Visual Studio Solution from below link:
Calling WCF Service from Client Side

Thanks.