Creating and Consuming a WCF Service in Silverlight

Posted by: Suprotim Agarwal , on 11/12/2008, in Category Silverlight 2, 3, 4 and 5
Views: 110204
Abstract: 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.
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.
I am using Visual Studio 2008 with SP1 and am using the final release of Silverlight. If you are using Silverlight Beta 2, check Silverlight 2 Beta 2 TO Silverlight 2 Final Release - A Complete Step By Step Guide for Upgrading your Development Environment. This article also makes use of the new language extensions of C# 3.0/ VB 9.0. For those who are not familiar with these new language features, check Getting Ready for .NET 3.5 and LINQ – Exploring C# 3.0. VB.NET users, check over here.
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.
WCF Service Template
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.
Sample Service
Click the WSDL (http://localhost:49551/SampleService.svc?wsdl) to view the operations and bindings.
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
ServiceWCFReference
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:
Running App
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.
 If you liked the article,  Subscribe to my RSS Feed.
Give me a +1 if you think it was a good article. Thanks!
Recommended Articles
Suprotim Agarwal, ASP.NET Architecture MVP, MCSD, MCAD, MCDBA, MCSE, is the CEO of A2Z Knowledge Visuals Pvt. He primarily works as an Architect Consultant and provides consultancy on how to design and develop .NET centric database solutions.

Suprotim is the founder and primary contributor to DotNetCurry, SQLServerCurry and DevCurry. He has also written an EBook 51 Recipes using jQuery with ASP.NET Controls.

Follow him on twitter @suprotimagarwal


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by geordie on Tuesday, December 2, 2008 12:47 PM
i am running this in VB, changed some names for my application and getting
[InvalidOperationException: The type 'NCPractice.Web.NCPracticeWcfService', provided as the Service attribute value in the ServiceHost directive could not be found.]
   System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) +4072054
   System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath) +11656060
   System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +42
   System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +479

any ideas would be appreciated
Comment posted by geordie on Tuesday, December 2, 2008 12:48 PM
i am running this in VB, changed some names for my application and getting
[InvalidOperationException: The type 'NCPractice.Web.NCPracticeWcfService', provided as the Service attribute value in the ServiceHost directive could not be found.]
   System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) +4072054
   System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath) +11656060
   System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +42
   System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +479

any ideas would be appreciated
Comment posted by Quintus on Wednesday, February 4, 2009 12:41 AM
Thanks for the excellent artical. I am building a similar application. Everything working fine in my development environment. Now I want to deploy to a Windows shared hosting account (ex. http://www.mysite.com). Where I can find the information about what files should be copied to where. Is any file need to be modified before coping to new location?. Thank you in advance.
Comment posted by parth on Wednesday, March 25, 2009 2:38 AM
how to insert data into database using WCF service???
pls reply or send a sample project if u hv created a one...
Comment posted by Jack on Wednesday, March 25, 2009 3:07 PM
Good job! What happens if an objcet is added into the Customer class such as public object CustomerProfile {set; get;}? Or can we pass a customized object from WCF wervice to a silverlight application?
Comment posted by shwetamber on Thursday, April 9, 2009 10:34 AM
when i am take datagrid in my page.xaml, it showing error
Error   
[The type 'data:DataGrid' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.]
plz give the solution
Comment posted by rakesh on Monday, April 20, 2009 6:40 AM
how to insert data using wcf service....plz suggest a book for silverlight in which examples given......
Comment posted by Suprotim Agarwal on Tuesday, April 21, 2009 8:51 AM
Rakesh: Here's a good book
http://www.google.co.in/url?sa=U&start=4&q=http://www.amazon.com/Data-Driven-Services-Silverlight-John-Papa/dp/0596523092&ei=CMHtSdXpN8GTkAW044mkDw&usg=AFQjCNG35Z6TjiTMA_j6BoJEj5rpIZw0GQ
Comment posted by rahul on Tuesday, April 28, 2009 3:24 AM
how to insert update and delete in silverlight....plz give an example with all steps....
Comment posted by Ravi Kaushika on Tuesday, May 5, 2009 10:30 AM
the article is fine.  how do you add a new wcf project (not a page/2 files) to an existing silver light solution that contains MySLProject and MySLProject.Web project folders.  thanks for your page.
Comment posted by G on Monday, May 18, 2009 5:26 PM
I had the InvalidOperationException error too using vb, I fixed it by removing the namespace identifiers from both the SampleService.svc and the Customer.vb.
Comment posted by Anil Pandey on Wednesday, August 5, 2009 2:22 AM
Very nice article. It is working for me in just  one shot..

can you please let me know how can i make this service as dynamic so that is there is any change in the table i mean the new record is added the record will automatically come in the user scree..


Thanks
Anil Kumar Pandey
http://mannpandey.blogspot.com
Comment posted by Eswar on Tuesday, August 11, 2009 11:47 AM
Excellent article. I was like nuts not knowing how to bind values to the silverlight datagrid from the database. This article was so nice that the author has explained it step by step, which even a person not knowing .Net can understand. We expect more like this from you. Thanks a lot.
Comment posted by Jack Baston on Friday, September 25, 2009 4:34 PM
I built a Silverlight enabled Web Service just as you defined in this article. However, when I go to Add A Service Reference I get:
"The type 'SilverlightWithWCFService.Web.SampleService1', provided as the Service attribute value in the ServiceHost directive could not be found."
Could you help?
Comment posted by gopalchettri on Sunday, November 29, 2009 1:25 AM
Hi Pinal. Thanks for sharing this mini tutorial.Looking after for getting data from the MySql.
One more thing, i want the user in silverlight place the query for example (roll no) and with the help of wcf how to retrieve the all the details of the student having the roll no (inserted) with all validation.Waiting reply. and Thanks once again.
Comment posted by ajstaggs on Friday, January 22, 2010 1:05 PM
This is a great tutorial and is exactly what I was looking for. Everything went great until the very end when I try to call client.CustomerListAsync() in vb. It gives me the error 'CustomerListAsync is not a member of SilverlightWithWCFService.CustomerService.SampleServiceClient(). Can you any help as to what the problem might be? Thanks.
Comment posted by pn on Tuesday, April 20, 2010 10:32 AM
I'm getting the following error:

An error occurred while trying to make a request to URI 'http://localhost:2019/Branches.svc'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

Any suggestions?
Comment posted by erum on Friday, May 28, 2010 7:12 AM
i need to call tehe hellworld service   [OperationContract]
        public string HelloWorld()
        {
            return "Helloworld";
        }

i have this in the same service please help me
Comment posted by EM on Friday, July 30, 2010 3:01 PM
Very nice, thank you for your excellent example.  I recommend following the code exactly then use that model to make your customizations.
Comment posted by tech on Wednesday, August 25, 2010 2:23 PM
By far the best tutorial on WCF service.  Thanks a lot
Comment posted by NITIN Bansal on Friday, December 17, 2010 10:57 AM
Thanks,
very good article ,this article solve my problem for connecting silverlight to database
Comment posted by Nupur Bakshi on Tuesday, December 21, 2010 2:14 AM
Hello Sir,

I am developing a project in WCF in which I am using WCF Message Based Security with UserNamePassword Client credentials for authenticating the Client.I have also created X509 certificates and provide access to Claims using Claims Based Authorization.Everything is working fine as When I initially call the operation of the service it asks for the authentication of the client and after authenticating the Client it provides access to the operation which is accurately done but when I call another operation from the same service it again asks for authentication which is creating a problem as I don't want to authenticate the Client again and again on every method(operation) call of the same service.Is there any way to retain the Client Credentials so that I would not have to re-authenticate the Client on every method(operation) call.Please help me in this.This is my first project in WCF so please provide me the step by step guidance on how to do it.I will be thankful to you.
Comment posted by prabhakar on Monday, February 14, 2011 4:27 AM
good explw
Comment posted by Adam Estrada on Thursday, February 17, 2011 12:47 PM
Where does new EventHandler<CustomerListCompletedEventArgs> come from? I am stuck at where to find CustomerListCompletedEventArgs in my project...
Comment posted by CR on Wednesday, March 2, 2011 5:50 PM
Thank you for posting such a thorough article. I am especially grateful for your inclusion of both VB and C#. Your examples worked for me without issue in Silverlight 4. Great job, Mr. Agarwal!
Comment posted by DaveCS on Sunday, April 10, 2011 2:13 PM
The VB example is wrong.  In the service class it does loop through the database fields and does add the properties to the Customer class.

However, trying to bind the output collection e.result is empty.

Private Sub client_CustomerListCompleted(ByVal sender As Object, ByVal e As CustomerListCompletedEventArgs)

        CustomerGrid.ItemsSource = e.Result 'no values
    End Sub

If you would like to test this yourself insert this code.

ListBox1.Items.Add(e.Result.Count)

The the listbox will output the number 0


Comment posted by Carol on Thursday, April 14, 2011 5:07 AM
@DaveCS: Quite possible. The VB code is translated using a conversion tool and is untested.

Carol
- Site Editor
Comment posted by Lynn Johnson on Saturday, June 25, 2011 9:11 PM
I followed your VB example only I was using VS 2010.  When I look in Web.Config I see the following in the services section:
        <services>
            <service name="SilverlightWithWCFService.Web.SampleService">
                <endpoint address="" binding="customBinding" bindingConfiguration="SilverlightWithWCFService.Web.SampleService.customBinding0"
                    contract="SilverlightWithWCFService.Web.SampleService" />
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            </service>
        </services>
I was of the impression from your comments that this would use basicHTTPBinding.  At any rate, I am getting an error when I try to add the Service Reference (I am using port 54437):

'http://localhost:54437/SampleService.svc'.
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
If the service is defined in the current solution, try building the solution and adding the service reference again.

Do you have any idea what might be wrong?
Comment posted by Animesh on Friday, July 22, 2011 5:17 AM
Please provide the right code for vb.net//// URGENT
Comment posted by John Nichols on Tuesday, July 26, 2011 8:46 PM
I keyed in the sample and I get the same error I got when I tried my own Vb Silverlight 3 app to consume a WCF service.  When I add the event handler, just like your example, I get the following error on the "AddHandler" line:
"... Does not have signature compatible with a delegate".  I have added the Service Reference to the WCF Silverlight Service, but I am getting this error when I key in your example and others.  Am I missing something?
Comment posted by bhargavi on Friday, September 23, 2011 7:37 AM
yes,you had said how to create & communicate with the wcf enable service.can u plz give the code to retrive the data from the database with hyperlink button(i.e retrive data when i click hyperlink button) in to the data grid.and also give the code to insert data into the database in siverlight4
Comment posted by Oded Dror on Sunday, October 30, 2011 7:05 PM
Hi Suprotim,

Can you email me the VB code for this article please
I try to follow but with no sucsess

Thanks,
Oded Dror
Comment posted by meenu on Saturday, May 19, 2012 12:11 AM
Can anybdy help me to pass parameter to the query in svc.I did like as follows.But error is triggering

<OperationContract()> _
    Public Function CustomerList(Condition As String) As List(Of comboloadclass)
        Dim nwConn As String = System.Configuration.ConfigurationManager.ConnectionStrings("DBConn").ConnectionString
        Dim custList = New List(Of comboloadclass)()
        Using conn As New SqlConnection(nwConn)
            Const sql As String = "Select * from EmpInfo" & " & Condition & "
            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 comboloadclass With {.ename = dr.GetString(1)}
                        custList.Add(cust)
                    Loop
                End If
                Return custList
            End Using
        End Using
    End Function
Comment posted by meenu on Saturday, May 19, 2012 1:42 AM
Dear Friend ,Can any bdy help me to solve my following issue posted here

http://forums.silverlight.net/t/255884.aspx/1?Pass+parameter+from+xaml+to+svc
Comment posted by aryan patel on Thursday, October 4, 2012 7:00 AM
what is this yar ??
its not working .....

cmbDepartment.ItemsSource = e.Result;

combox fill like is projectname.servicereference1.methodname
Comment posted by Alex on Monday, February 25, 2013 1:55 PM
My DataGrid is empty. I also get an error: "The remote server returned an error: NotFound." and it looks as if it is targeting my Web Service ClientList method. I have verified the service is running and am using Fiddler to try to troubleshoot. Any ideas?
Comment posted by aravind on Wednesday, October 30, 2013 6:42 AM
sir i am getting an error


Error   1   Inconsistent accessibility: return type 'System.Collections.Generic.List<testsilverlight.Web.Person>' is less accessible than method 'testsilverlight.Web.Service3.GetAllPersons()'   C:\Documents and Settings\new\my documents\visual studio 2010\Projects\testsilverlight\testsilverlight.Web\Service3.svc.cs   20   29   testsilverlight.Web

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel