Creating and Consuming a WCF Service in Silverlight
In this article, we will create a Silverlight application that communicates with a WCF service to consume data. We will first create a WCF service that connects to the Northwind database and retrieves Customer details. We will then consume this WCF Service and bind the data to a DataGrid in Silverlight.
Let us get started
Step 1: Open VS 2008 > File menu > New > Project > Select Silverlight from the Project types > Select Silverlight Application from the Visual Studio installed templates. Type the name as SilverlightWithWCFService and click OK.
Step 2: In the 'Add Silverlight Application' box, select 'Add a new ASP.NET Web project to the solution to host Silverlight' > Select ‘ASP.NET Web Application Project' as the Project Type and the Name as 'SilverlightWithWCFService.Web' for the application. Press OK.
Creating a Silverlight enabled WCF Service
Step 3: We will now add a WCF Service to this project. Right click the SilverlightWithWCFService.Web project > Add > New Item > Select ‘Silverlight’ in the Categories page > Silverlight-enabled WCF Service > Type name as ‘SampleService.svc’ > Add.
Note: Creating a WCF Service using the ‘Silverlight-enabled WCF Service’ template sets the correct configuration for using WCF. It sets the binding to basicHttpBinding and makes the service ASP.NET compatible. If you have existing WCF services, you can make them work with Silverlight by changing the default binding from wsHttpBinding to basicHttpBinding.
For simplicity sake, I have not hosted the service on IIS. I am using the server that comes built-in with Visual Studio 2008. The server automatically allocates a port number. If you would like to keep the port number fixed, Right click the project > select the ‘Web’ tab > Select the radiobutton ‘Specific port’ > I am using the port 49551. Build the Solution.
Note: If the protocol, path or the port number of the service differs from that of the Silverlight application, it is a Cross Domain call in Silverlight. You would need a clientaccesspolicy.xml kept in the root of the server where the service is hosted in order to make Cross Domain calls. Read more about it over here
Step 4: We need to query the ‘Customers’ table in the Northwind db and return a list of type Customers. Now C# 3.0/ VB 9.0 introduces features like the ‘Anonymous type’ to cut down on the code required to create and instantiate a class using ‘the old way’. However, if you have to pass the result to a webservice or to a different part of your application, you would need to define a class as shown below. Right click the 'SilverlightWithWCFService.Web' project > Add > Class > we will call our class ‘Customer’.
C#
namespace SilverlightWithWCFService.Web
{
public class Customer
{
public string CustomerName { get; set; }
public string CompanyName { get; set; }
public string ContactName { get; set; }
}
}
VB.NET
Namespace SilverlightWithWCFService.Web
Public Class Customer
Private privateCustomerName As String
Public Property CustomerName() As String
Get
Return privateCustomerName
End Get
Set(ByVal value As String)
privateCustomerName = value
End Set
End Property
Private privateCompanyName As String
Public Property CompanyName() As String
Get
Return privateCompanyName
End Get
Set(ByVal value As String)
privateCompanyName = value
End Set
End Property
Private privateContactName As String
Public Property ContactName() As String
Get
Return privateContactName
End Get
Set(ByVal value As String)
privateContactName = value
End Set
End Property
End Class
End Namespace
Note: C# 3.0 supports Automatic properties whereas VB.NET 9.0 does not.
Step 5: In your web.config, create a <connectingString> as shown below:
<connectionStrings>
<add name="NorthwindConnectionString" connectionString="Data Source=(local);Initial Catalog=Northwind;Integrated Security=True"/>
</connectionStrings>
Now go back to you SampleService.cs or vb and write the following code
C#
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
namespace SilverlightWithWCFService.Web
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SampleService
{
[OperationContract]
public List<Customer> CustomerList()
{
string nwConn = System.Configuration.ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;
var custList = new List<Customer>();
using (SqlConnection conn = new SqlConnection(nwConn))
{
const string sql = @"SELECT TOP 10 CustomerID, CompanyName, ContactName FROM Customers";
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
SqlDataReader dr = cmd.ExecuteReader(
CommandBehavior.CloseConnection);
if (dr != null)
while (dr.Read())
{
var cust = new Customer
{
CustomerName = dr.GetString(0),
CompanyName= dr.GetString(1),
ContactName = dr.GetString(2)
};
custList.Add(cust);
}
return custList;
}
}
}
// Add more operations here and mark them with [OperationContract]
}
}
VB.NET
Imports System.ServiceModel
Imports System.ServiceModel.Activation
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Namespace SilverlightWithWCFService.Web
<ServiceContract(Namespace := ""), AspNetCompatibilityRequirements(RequirementsMode := AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class SampleService
<OperationContract> _
Public Function CustomerList() As List(Of Customer)
Dim nwConn As String = System.Configuration.ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString
Dim custList = New List(Of Customer)()
Using conn As New SqlConnection(nwConn)
Const sql As String = "SELECT TOP 10 CustomerID, CompanyName, ContactName FROM Customers"
conn.Open()
Using cmd As New SqlCommand(sql, conn)
Dim dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
If dr IsNot Nothing Then
Do While dr.Read()
Dim cust = New Customer With {.CustomerName = dr.GetString(0), .CompanyName= dr.GetString(1), .ContactName = dr.GetString(2)}
custList.Add(cust)
Loop
End If
Return custList
End Using
End Using
End Function
' Add more operations here and mark them with [OperationContract]
End Class
End Namespace
The code shown above connects to the Northwind database and pulls the TOP 10 Customer records from the Customers table. The return type is a List<> of type Customers. You can test this service by right clicking the Service > View in Browser.
Creating Silverlight Client to consume WCF Service
Once the WCF Service has been created, it’s time to consume this service using Silverlight. Follow these steps:
Step 6: We will now create a Silverlight client that will consume the WCF service. Right-click the SilverlightWithWCFService project (one containing Page.xaml) in Solution Explorer > Select Add Service Reference > Enter the url where the service is running http://localhost:49551/SampleService.svc > Click the Go button and the service will be displayed as shown below along with the operations it supports
I have renamed the Namespace field as ‘CustomerService’. Click Ok.
You will observe that a new folder called ‘Service References’ gets created which contains class and methods to call the service.
Go to Page.Xaml.cs or Page.Xaml.vb and add the following namespaces
C#
using System.ServiceModel;
using SilverlightWithWCFService.CustomerService;
VB.NET
Imports System.ServiceModel
Imports SilverlightWithWCFService.CustomerService
We will now call the service. All WCF service calls are made asynchronously. Since the call is asynchronous, we will need an asynchronous method that starts the communication and an event which will be raised when the call completes as shown below:
C#
public Page()
{
InitializeComponent();
SampleServiceClient client = new SampleServiceClient();
client.CustomerListCompleted += new EventHandler<CustomerListCompletedEventArgs>(client_CustomerListCompleted);
client.CustomerListAsync();
}
void client_CustomerListCompleted(object sender, CustomerListCompletedEventArgs e)
{
}
VB.NET
Public Sub New()
InitializeComponent()
Dim client As New SampleServiceClient()
AddHandler client.CustomerListCompleted, AddressOf client_CustomerListCompleted
client.CustomerListAsync()
End Sub
Private Sub client_CustomerListCompleted(ByVal sender As Object, ByVal e As CustomerListCompletedEventArgs)
End Sub
Step 7: Add a DataGrid from the Silverlight Controls Toolbox to the Page.Xaml.
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid x:Name="CustomerGrid" Margin="3"></data:DataGrid>
</Grid>
In the client_CustomerListCompleted, bind the Grid with the result.
C#
void client_CustomerListCompleted(object sender, CustomerListCompletedEventArgs e)
{
CustomerGrid.ItemsSource = e.Result;
}
VB.NET
Private Sub client_CustomerListCompleted(ByVal sender As Object, ByVal e As CustomerListCompletedEventArgs)
CustomerGrid.ItemsSource = e.Result
End Sub
On running the application, the results will be displayed as shown below:
That’s all that is required to configure the Grid. You will notice that the Grid contains all the standard features to Sort, Select, Resize columns, Edit etc and is quiet customizable. In this article, we saw how to create and consume a WCF service using a Silverlight client. I hope this article was useful and I thank you for viewing it.