Consuming Binary Encoded WCF 4.0 Service in Silverlight 3.0 Applications

Posted by: Mahesh Sabnis , on 3/22/2010, in Category Silverlight 2, 3, 4 and 5
Views: 35071
Abstract: This article demonstrates how a binary encoded WCF service can be consumed in Silverlight 3.0 client for messaging optimization.
Consuming Binary Encoded WCF 4.0 Service in Silverlight 3.0 Applications
 
I suppose with the .NET 4.0 release round the corner, most of you must have started exploring WCF 4.0. As of this writing, Microsoft has released Visual Studio 2010 RC and you can download from the following link.
With VS 2010, lots of new features have been introduced for developers to make their life easier. But one of the very exciting feature provided is inbuilt support to Silverlight. For all those who use VS2008 and Silverlight 3.0 may know that you need to install Silverlight 3.0 SDK and toolkit externally. VS2008 does not provide any drag-drop support for Silverlight controls on the designer canvas, you can drag-drop XAML of Elements in the XAML designer or need to use Expression Blend to design.        
With VS2010, developers are provided with easy to use Silverlight 3.0 features like element drag-drop on the designer canvas, easy to use property window etc. For charting, you need to download Silverlight 3.0 Charting toolkit from the following link: http://www.codeplex.com/Silverlight
When you install it, you will get the necessary charting controls and other controls in VS2010 toolbox for Silverlight 3.0 applications.
Now during last week, I was conducting a training for a client on Silverlight 3.0. In this training, I was discussing features of Silverlight 3.0 for application development (Note: Silverlight 4 is going to be released soon). One of the attendees asked me a question if it was possible to use WCF 4.0 in Silverlight 3.0 and can we have some sort of message encoding so that the message size can be handled. Silverlight 3.0 has support for binary encoded message communication to WCF service. These messages are comparatively small in size and help in improving performance of communication.
In this article, I have used VS2010 RC, WCF 4.0 and Silverlight 3.0. The service is hosted on IIS 7.5 and makes a query to a Sql Server 2008 database to fetch the data. This data is then displayed in a Silverlight 3.0 client application.
Task 1: Database Table creation.
 
Step 1: Create database ‘Company’.
Step 2: Add following tables with columns:
EmpNo
The above table is used to store Employee information.
CompanyID
The above table is used to store, company wise quarter wise sales information.
ItemNo
The above table is used to store ItemName wise sales quantity data.
StateName
The above table is used to store state wise sales quantity.
Task 2: Creating WCF 4.0 Service.
 
Step 1: Open VS2010 and create a blank solution > name it as ‘WCF_Silverlight_BinaryEncodedCall’.
Step 2: To this solution, add a new WCF Service Application and name it as ‘WCF_BinaryEncodedStatasticService’ as shown below. Make sure that .NET 4.0 is selected in the dropdown:
AddNewProject
Step 3: Rename ‘Iservice1.cs’ to ‘IStatasticService.cs’. Write the following code in it:
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
 
namespace WCF_BinaryEncodedStatasticService
{
    [ServiceContract]
    public interface IStatasticService
    {
 
        [OperationContract]
        List<clsSales> GetSalesDetails();
 
        [OperationContract]
        List<clsSalesData> GetSalesData();
 
        [OperationContract]
        List<clsStatewiseSales> GetStatewiseSales();
    }
 
    [DataContract]
    public class clsSales
    {
        [DataMember]
        public int CompanyId { get; set; }
        [DataMember]
        public string CompanyName { get; set; }
        [DataMember]
        public int Sales;
    }
    [DataContract]
    public class clsSalesData
    {
        [DataMember]
        public string ItemName { get; set; }
        [DataMember]
        public int SalesQty { get; set; }
    }
 
    [DataContract]
    public class clsStatewiseSales
    {
        [DataMember]
        public string StateName { get; set; }
        [DataMember]
        public decimal SalesQuantity { get; set; }
    }
 
}
 
VB.NET (Converted code)
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Web
Imports System.Text
 
Namespace WCF_BinaryEncodedStatasticService
      <ServiceContract> _
      Public Interface IStatasticService
 
            <OperationContract> _
            Function GetSalesDetails() As List(Of clsSales)
 
            <OperationContract> _
            Function GetSalesData() As List(Of clsSalesData)
 
            <OperationContract> _
            Function GetStatewiseSales() As List(Of clsStatewiseSales)
      End Interface
 
      <DataContract> _
      Public Class clsSales
            Private privateCompanyId As Integer
            <DataMember> _
            Public Property CompanyId() As Integer
                  Get
                        Return privateCompanyId
                  End Get
                  Set(ByVal value As Integer)
                        privateCompanyId = value
                  End Set
            End Property
            Private privateCompanyName As String
            <DataMember> _
            Public Property CompanyName() As String
                  Get
                        Return privateCompanyName
                  End Get
                  Set(ByVal value As String)
                        privateCompanyName = value
                  End Set
            End Property
            <DataMember> _
            Public Sales As Integer
      End Class
      <DataContract> _
      Public Class clsSalesData
            Private privateItemName As String
            <DataMember> _
            Public Property ItemName() As String
                  Get
                        Return privateItemName
                  End Get
                  Set(ByVal value As String)
                        privateItemName = value
                  End Set
            End Property
            Private privateSalesQty As Integer
            <DataMember> _
            Public Property SalesQty() As Integer
                  Get
                        Return privateSalesQty
                  End Get
                  Set(ByVal value As Integer)
                        privateSalesQty = value
                  End Set
            End Property
      End Class
 
      <DataContract> _
      Public Class clsStatewiseSales
            Private privateStateName As String
            <DataMember> _
            Public Property StateName() As String
                  Get
                        Return privateStateName
                  End Get
                  Set(ByVal value As String)
                        privateStateName = value
                  End Set
            End Property
            Private privateSalesQuantity As Decimal
            <DataMember> _
            Public Property SalesQuantity() As Decimal
                  Get
                        Return privateSalesQuantity
                  End Get
                  Set(ByVal value As Decimal)
                        privateSalesQuantity = value
                  End Set
            End Property
      End Class
 
End Namespace
 
The above code shows DataContracts and ServiceContract used to create the WCF service
Step 4: Rename, ‘Service1.cs’ to ‘StatasticService.cs’. This is the WCF service class and implements ‘IStatasticService’ interface as shown below:
Note: I have used the connection string at a number of places here as I built these method individually, but ideally you could use a ConnectionManager class to read the string from a config file. Search out on google and there are plenty of solutions out there.
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Data.SqlClient;
 
namespace WCF_BinaryEncodedStatasticService
{
    public class StatasticService : IStatasticService
    {
        SqlConnection Conn;
        SqlCommand Cmd;
        SqlDataReader Reader;
 
 
        public List<clsSales> GetSalesDetails()
        {
            try
            {
                Conn = new SqlConnection("Data Source=.\\dbserver;Initial Catalog=Company;Integrated Security=SSPI");
                List<clsSales> lstSales = new List<clsSales>();
                Conn.Open();
                Cmd = new SqlCommand();
                Cmd.Connection = Conn;
                Cmd.CommandText = "Select CompanyId,CompanyName, (Q1+Q2+Q3+Q4) as Sales from Sales";
 
                Reader = Cmd.ExecuteReader();
 
                while (Reader.Read())
                {
                    lstSales.Add
                        (
                                new clsSales()
                                {
                                    CompanyId = Convert.ToInt32(Reader["CompanyId"]),
                                    CompanyName = Reader["CompanyName"].ToString(),
                                    Sales = Convert.ToInt32(Reader["Sales"])
                                }
                        );
                }
                return lstSales;
            }
            catch (Exception ex)
            {
            }
            finally
            {
                Reader.Close();
                Conn.Close();
            }
 
 
        }
 
        public List<clsSalesData> GetSalesData()
        {
            try
            {
                Conn = new SqlConnection("Data Source=.\\dbserver;Initial Catalog=Company;Integrated Security=SSPI");
                List<clsSalesData> lstSalesData = new List<clsSalesData>();
                Conn.Open();
                Cmd = new SqlCommand();
                Cmd.Connection = Conn;
                Cmd.CommandText = "Select Top 8 ItemName,SalesQty from SalesData";
                Reader = Cmd.ExecuteReader();
 
                while (Reader.Read())
                {
                    lstSalesData.Add
                        (
                            new clsSalesData()
                            {
                                ItemName = Reader["ItemName"].ToString(),
                                SalesQty = Convert.ToInt32(Reader["SalesQty"])
                            }
                         );
                }
                return lstSalesData;
            }
            catch (Exception ex)
            {
 
            }
            finally
            {
                Reader.Close();
                Conn.Close();
            }
 
        }
 
        public List<clsStatewiseSales> GetStatewiseSales()
        {
            try
            {
                Conn = new SqlConnection("Data Source=.\\dbserver;Initial Catalog=Company;Integrated Security=SSPI");
                List<clsStatewiseSales> lstStatewiseSales = new List<clsStatewiseSales>();
                Conn.Open();
                Cmd = new SqlCommand();
                Cmd.Connection = Conn;
 
                Cmd.CommandText = "Select StateName,Salesquantity from Statewisesales";
                Reader = Cmd.ExecuteReader();
 
                while (Reader.Read())
                {
                    lstStatewiseSales.Add
                        (
                            new clsStatewiseSales()
                            {
                                StateName = Reader["StateName"].ToString(),
                                SalesQuantity = Convert.ToInt32(Reader["Salesquantity"])
                            }
                         );
                }
                return lstStatewiseSales;
            }
            catch (Exception ex)
            {
 
            }
            finally
            {
                Reader.Close();
                Conn.Close();
            }
 
        }
    }
}
 
 
VB.NET (Converted code)
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Web
Imports System.Text
Imports System.Data.SqlClient
 
Namespace WCF_BinaryEncodedStatasticService
      Public Class StatasticService
            Implements IStatasticService
            Private Conn As SqlConnection
            Private Cmd As SqlCommand
            Private Reader As SqlDataReader
 
 
            Public Function GetSalesDetails() As List(Of clsSales)
                  Try
                        Conn = New SqlConnection("Data Source=.\dbserver;Initial Catalog=Company;Integrated Security=SSPI")
                        Dim lstSales As New List(Of clsSales)()
                        Conn.Open()
                        Cmd = New SqlCommand()
                        Cmd.Connection = Conn
                        Cmd.CommandText = "Select CompanyId,CompanyName, (Q1+Q2+Q3+Q4) as Sales from Sales"
 
                        Reader = Cmd.ExecuteReader()
 
                        Do While Reader.Read()
                              lstSales.Add (New clsSales() With {.CompanyId = Convert.ToInt32(Reader("CompanyId")), .CompanyName = Reader("CompanyName").ToString(), .Sales = Convert.ToInt32(Reader("Sales"))})
                        Loop
                        Return lstSales
                  Catch ex As Exception
                  Finally
                        Reader.Close()
                        Conn.Close()
                  End Try
 
 
            End Function
 
            Public Function GetSalesData() As List(Of clsSalesData)
                  Try
                        Conn = New SqlConnection("Data Source=.\dbserver;Initial Catalog=Company;Integrated Security=SSPI")
                        Dim lstSalesData As New List(Of clsSalesData)()
                        Conn.Open()
                        Cmd = New SqlCommand()
                        Cmd.Connection = Conn
                        Cmd.CommandText = "Select Top 8 ItemName,SalesQty from SalesData"
                        Reader = Cmd.ExecuteReader()
 
                        Do While Reader.Read()
                              lstSalesData.Add (New clsSalesData() With {.ItemName = Reader("ItemName").ToString(), .SalesQty = Convert.ToInt32(Reader("SalesQty"))})
                        Loop
                        Return lstSalesData
                  Catch ex As Exception
 
                  Finally
                        Reader.Close()
                        Conn.Close()
                  End Try
 
            End Function
 
            Public Function GetStatewiseSales() As List(Of clsStatewiseSales)
                  Try
                        Conn = New SqlConnection("Data Source=.\dbserver;Initial Catalog=Company;Integrated Security=SSPI")
                        Dim lstStatewiseSales As New List(Of clsStatewiseSales)()
                        Conn.Open()
                        Cmd = New SqlCommand()
                        Cmd.Connection = Conn
 
                        Cmd.CommandText = "Select StateName,Salesquantity from Statewisesales"
                        Reader = Cmd.ExecuteReader()
 
                        Do While Reader.Read()
                              lstStatewiseSales.Add (New clsStatewiseSales() With {.StateName = Reader("StateName").ToString(), .SalesQuantity = Convert.ToInt32(Reader("Salesquantity"))})
                        Loop
                        Return lstStatewiseSales
                  Catch ex As Exception
 
                  Finally
                        Reader.Close()
                        Conn.Close()
                  End Try
 
            End Function
 
 
      End Class
End Namespace
 
The above code shows the implementation of the WCF service. The code makes call to the Sql Server 2008 database and fetches data from it.
Step 5: Open Web.Config file and write following configuration:
<?xml version="1.0"?>
<configuration>
 
 <system.web>
    <compilation debug="true" targetFramework="4.0" />
 </system.web>
 <system.serviceModel>
    <services>
      <service name="WCF_BinaryEncodedStatasticService.StatasticService"
                behaviorConfiguration="ServBehave">
        <endpoint
           address=""
            binding="customBinding"
            bindingConfiguration="customBinaryEncodedBinding"
            contract="WCF_BinaryEncodedStatasticService.IStatasticService"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServBehave">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <customBinding>
        <bindingname="customBinaryEncodedBinding">
          <binaryMessageEncoding></binaryMessageEncoding>
          <httpTransport></httpTransport>
        </binding>
      </customBinding>
    </bindings>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
 </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
 </system.webServer>
 
</configuration>
 
The above configurations are very important. It shows the following:
·         It specifies the runtime used to execute WCF service. The target framework attribute demands .NET 4.0 to installed on the web server.
·         In the <bindings>, custom binding specifies that the WCF runtime is going to use binary encoding for message transport. So though the service is hosted on IIS which uses Http transport, the binary messages will be carried over it. This makes the communication more optimized, so if there are multiple clients communicating with the WCF service at a time, for all such clients, optimized messaging will be provided by WCF.
Step 6: Make the following changes in ‘StatasticService.svc’ file by right clicking and selecting ‘View Markup’ on it.
<%@ServiceHost="" Language="C#" Debug="true"
Service="WCF_BinaryEncodedStatasticService.StatasticService"
CodeBehind="StatasticService.svc.cs" %>
Task 3: Deploying WCF service on IIS by using the ‘Publish’ mechanism of VS2010 RC and Setting Database Connectivity.
 
Step 1: Right click on the WCF service project and select ‘Publish’ > you will get the following window. Select the IIS path and click on ‘Publish’.
PublishProfile
Note: If the server on which you want to publish this WCF service contains ASP.NET 2.0 runtime and ASP.NET 4.0 runtime, then you need to be more careful, because you need to make some changes in Application Pool properties so that service will use .NET 4.0 and will communicate to the Database server.
(Here I am using Windows 7 Enterprise, IIS 7.5 and Sql Server 2008. These are the steps I have followed to make my solution workable, if you have any better settings, share your solution in the comments section. They are welcome!)
Step 2: In the SQL Service 2008, expand Object explorer. Select Security->Logins and add the ‘NT Authority\Network Service’ user as below:
Security
Step 3: Open IIS 7.0 and select Application Pools. You will get the list of all application pools currently available. Select ASP.NET v40 and select advance Settings. From the Advance Settings window, select Process Model and change Identity form ‘ApplicationPoolIdentity’ to ‘Local System’ as below:
Connections
Step 4: Browse the svc file by right clicking on it, you should see the page with wsdl link in the browser.
Task 4: Creating Silverlight 3.0 client application.
 
Step 1: In the solution, right click and add a new Silverlight application, name it a ‘Silv3_StatasticsClient’. Once you click OK, VS2010 will ask for the settings for the Silverlight project as shown below:
SilverlightApplication
The ‘Options’ shows Silverlight versions installed on the machine.
Step 2: Since I am going to use the charting feature of Silverlight, I have done a drag-drop for all charts which I have downloaded from this link. After the drag-drop, my Xaml looks as shown below:
<UserControl x:Class="Silv3_StatasticsClient.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="800" d:DesignWidth="800" xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"Loaded="UserControl_Loaded">
 
 <Grid x:Name="LayoutRoot" Background="White" Height="800" Width="800">
    <Grid.RowDefinitions>
      <RowDefinition Height="274*" />
      <RowDefinition Height="526*" />
    </Grid.RowDefinitions>
    <TextBlock Height="38" HorizontalAlignment="Left" Margin="66,17,0,0" Name="textBlock1" Text="Companywise Sales" VerticalAlignment="Top" Width="254" FontWeight="Bold" FontSize="20" />
    <TextBlock FontSize="20" FontWeight="Bold" Height="38" HorizontalAlignment="Left" Margin="450,17,0,0" Name="textBlock2" Text="Itemwise Sales"VerticalAlignment="Top"Width="254" />
    <TextBlock FontSize="20" FontWeight="Bold" Height="38" HorizontalAlignment="Left" Margin="41,34,0,0" Name="textBlock3" Text="Statewise Sales" VerticalAlignment="Top" Width="254" Grid.Row="1" />
    <chartingToolkit:Chart Height="190" HorizontalAlignment="Left" Margin="12,61,0,0"
                           Name="chartCompanywise" VerticalAlignment="Top" Width="363">
      <chartingToolkit:PieSeries DependentValuePath="Value" x:Name="pieCompanywise" IndependentValuePath="Key" ItemsSource="{Binding}" />
    </chartingToolkit:Chart>
    <chartingToolkit:Chart Height="197" HorizontalAlignment="Left" Margin="413,54,0,0" Name="chartItemwise"
                           VerticalAlignment="Top" Width="370">
 
      <chartingToolkit:LineSeries DependentValuePath="Value"
                                  x:Name="lineItemwise" IndependentValuePath="Key" ItemsSource="{Binding}" />
    </chartingToolkit:Chart>
    <chartingToolkit:Chart Grid.Row="1" Height="280" HorizontalAlignment="Left" Margin="19,72,0,0" Name="chartStatewise"
                            VerticalAlignment="Top" Width="341">
      <chartingToolkit:ColumnSeries DependentValuePath="Value"
                                     x:Name="columnStatewise" IndependentValuePath="Key" ItemsSource="{Binding}" />
    </chartingToolkit:Chart>
 </Grid>
</UserControl>
The design is as below:
Sales
(Note: Drag-drop of Chart element will display Column Series by default, so if you want change charts to any other type e.g. Pie, Line etc, then you need to make changes in the XAML).
Step 3: In the Silverlight project, add the WCF service reference and write the following Code in MainPage.Xaml.cs:
C#
MyRef.StatasticServiceClient Proxy;
        MyRef.clsSales objSales;
        MyRef.clsSalesData objSalesData;
        MyRef.clsStatewiseSales objStatewise;
 
        public MainPage()
        {
            InitializeComponent();
        }
 
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            Proxy = new MyRef.StatasticServiceClient();
            try
            {
                //Get Company wise Sales Details
                GetCompanywiseSalesDetails();
                //Get State wise Sales Details
            GetStatewiseSalesDetails();
             //   //Get Item wise Sales Details
               GetItemwiseSalesDetails();
            }
            catch (Exception ex)
            {
                HtmlPage.Window.Alert(ex.Message);
            }
        }
 
        private void GetCompanywiseSalesDetails()
        {
            Proxy.GetSalesDetailsCompleted += new EventHandler<MyRef.GetSalesDetailsCompletedEventArgs>(Proxy_GetSalesDetailsCompleted);
            Proxy.GetSalesDetailsAsync();
        }
 
        void Proxy_GetSalesDetailsCompleted(object sender, MyRef.GetSalesDetailsCompletedEventArgs e)
        {
            try
            {
                //Collect Results Here
                MyRef.clsSales[] colSalesDetails = e.Result;
                //KeyValuePair array is the data source used for all chart controls
                KeyValuePair<string, decimal>[] arrSalesDetails = new KeyValuePair<string, decimal>[colSalesDetails.Length];
 
                //Store Data from Result to the KeyValePair array
                int count = 0;
                foreach (var item in colSalesDetails)
                {
                    arrSalesDetails[count] = new KeyValuePair<string, decimal>(item.CompanyName, item.Sales);
                    count++;
                }
 
                //Display data in Coulumn Chart
                chartCompanywise.DataContext = arrSalesDetails;
 
                PieSeries pieSalesChart = chartCompanywise.Series[0] as PieSeries;
 
                pieSalesChart.ItemsSource = arrSalesDetails;
            }
            catch (Exception ex)
            {
                HtmlPage.Window.Alert(ex.Message);
            }
        }
 
   
 
        private void GetStatewiseSalesDetails()
        {
            Proxy.GetStatewiseSalesCompleted += new EventHandler<MyRef.GetStatewiseSalesCompletedEventArgs>(Proxy_GetStatewiseSalesCompleted);
            Proxy.GetStatewiseSalesAsync();
        }
        void Proxy_GetStatewiseSalesCompleted(object sender, MyRef.GetStatewiseSalesCompletedEventArgs e)
        {
            try
            {
                //Collect Results Here
                MyRef.clsStatewiseSales[] colStatewiseSalesDetails = e.Result;
                //KeyValuePair array is the data source used for all chart controls
                KeyValuePair<string, decimal>[] arrStatewiseSalesDetails = new KeyValuePair<string, decimal>[colStatewiseSalesDetails.Length];
 
                //Store Data from Result to the KeyValePair array
                int count = 0;
                foreach (var item in colStatewiseSalesDetails)
                {
                    arrStatewiseSalesDetails[count] = new KeyValuePair<string, decimal>(item.StateName, item.SalesQuantity);
                    count++;
                }
 
                //Display data in Coulumn Chart
                chartStatewise.DataContext = arrStatewiseSalesDetails;
 
                ColumnSeries columnStatewiseChart = chartStatewise.Series[0] as ColumnSeries;
 
                columnStatewiseChart.ItemsSource = arrStatewiseSalesDetails;
            }
            catch (Exception ex)
            {
                HtmlPage.Window.Alert(ex.Message);
            }
 
        }
 
        private void GetItemwiseSalesDetails()
        {
            Proxy.GetSalesDataCompleted += new EventHandler<MyRef.GetSalesDataCompletedEventArgs>(Proxy_GetSalesDataCompleted);
            Proxy.GetSalesDataAsync(); 
        }
 
        void Proxy_GetSalesDataCompleted(object sender, MyRef.GetSalesDataCompletedEventArgs e)
        {
            try
            {
                //Collect Results Here
                MyRef.clsSalesData[] colSalesItems = e.Result;
                //KeyValuePair array is the data source used for all chart controls
                KeyValuePair<string, decimal>[] arrSalesItems = new KeyValuePair<string, decimal>[colSalesItems.Length];
 
                //Store Data from Result to the KeyValePair array
                int count = 0;
                foreach (var item in colSalesItems)
                {
                    arrSalesItems[count] = new KeyValuePair<string, decimal>(item.ItemName, item.SalesQty);
                    count++;
                }
 
                //Display data in Coulumn Chart
                chartCompanywise.DataContext = arrSalesItems;
 
                LineSeries lineSalesChart = chartItemwise.Series[0] as LineSeries;
 
                lineSalesChart.ItemsSource = arrSalesItems;
            }
            catch (Exception ex)
           {
                HtmlPage.Window.Alert(ex.Message);
            }
        }
 
VB.NET (Converted Code)
 
Private Proxy As MyRef.StatasticServiceClient
            Private objSales As MyRef.clsSales
            Private objSalesData As MyRef.clsSalesData
            Private objStatewise As MyRef.clsStatewiseSales
 
            Public Sub New()
                  InitializeComponent()
            End Sub
 
            Private Sub UserControl_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
                  Proxy = New MyRef.StatasticServiceClient()
                  Try
                        'Get Company wise Sales Details
                        GetCompanywiseSalesDetails()
                        'Get State wise Sales Details
                  GetStatewiseSalesDetails()
                   '   //Get Item wise Sales Details
                     GetItemwiseSalesDetails()
                  Catch ex As Exception
                        HtmlPage.Window.Alert(ex.Message)
                  End Try
            End Sub
 
            Private Sub GetCompanywiseSalesDetails()
                  AddHandler Proxy.GetSalesDetailsCompleted, AddressOf Proxy_GetSalesDetailsCompleted
                  Proxy.GetSalesDetailsAsync()
            End Sub
 
            Private Sub Proxy_GetSalesDetailsCompleted(ByVal sender As Object, ByVal e As MyRef.GetSalesDetailsCompletedEventArgs)
                  Try
                        'Collect Results Here
                        Dim colSalesDetails() As MyRef.clsSales = e.Result
                        'KeyValuePair array is the data source used for all chart controls
                        Dim arrSalesDetails(colSalesDetails.Length - 1) As KeyValuePair(Of String, Decimal)
 
                        'Store Data from Result to the KeyValePair array
                        Dim count As Integer = 0
                        For Each item In colSalesDetails
                              arrSalesDetails(count) = New KeyValuePair(Of String, Decimal)(item.CompanyName, item.Sales)
                              count += 1
                        Next item
 
                        'Display data in Coulumn Chart
                        chartCompanywise.DataContext = arrSalesDetails
 
                        Dim pieSalesChart As PieSeries = TryCast(chartCompanywise.Series(0), PieSeries)
 
                        pieSalesChart.ItemsSource = arrSalesDetails
                  Catch ex As Exception
                        HtmlPage.Window.Alert(ex.Message)
                  End Try
            End Sub
 
      Private Sub GetStatewiseSalesDetails()
                  AddHandler Proxy.GetStatewiseSalesCompleted, AddressOf Proxy_GetStatewiseSalesCompleted
                  Proxy.GetStatewiseSalesAsync()
End Sub
 
      Private Sub Proxy_GetStatewiseSalesCompleted(ByVal sender As Object, ByVal e As MyRef.GetStatewiseSalesCompletedEventArgs)
                  Try
                        'Collect Results Here
                        Dim colStatewiseSalesDetails() As MyRef.clsStatewiseSales = e.Result
                        'KeyValuePair array is the data source used for all chart controls
                        Dim arrStatewiseSalesDetails(colStatewiseSalesDetails.Length - 1) As KeyValuePair(Of String, Decimal)
 
                        'Store Data from Result to the KeyValePair array
                        Dim count As Integer = 0
                        For Each item In colStatewiseSalesDetails
                              arrStatewiseSalesDetails(count) = New KeyValuePair(Of String, Decimal)(item.StateName, item.SalesQuantity)
                              count += 1
                        Next item
 
                        'Display data in Coulumn Chart
                        chartStatewise.DataContext = arrStatewiseSalesDetails
 
                        Dim columnStatewiseChart As ColumnSeries = TryCast(chartStatewise.Series(0), ColumnSeries)
 
                        columnStatewiseChart.ItemsSource = arrStatewiseSalesDetails
                  Catch ex As Exception
                        HtmlPage.Window.Alert(ex.Message)
                  End Try
 
      End Sub
 
      Private Sub GetItemwiseSalesDetails()
                  AddHandler Proxy.GetSalesDataCompleted, AddressOf Proxy_GetSalesDataCompleted
                  Proxy.GetSalesDataAsync()
      End Sub
 
      Private Sub Proxy_GetSalesDataCompleted(ByVal sender As Object, ByVal e As MyRef.GetSalesDataCompletedEventArgs)
                  Try
                        'Collect Results Here
                        Dim colSalesItems() As MyRef.clsSalesData = e.Result
                        'KeyValuePair array is the data source used for all chart controls
                        Dim arrSalesItems(colSalesItems.Length - 1) As KeyValuePair(Of String, Decimal)
 
                        'Store Data from Result to the KeyValePair array
                        Dim count As Integer = 0
                        For Each item In colSalesItems
                              arrSalesItems(count) = New KeyValuePair(Of String, Decimal)(item.ItemName, item.SalesQty)
                              count += 1
                        Next item
 
                        'Display data in Coulumn Chart
                        chartCompanywise.DataContext = arrSalesItems
 
                        Dim lineSalesChart As LineSeries = TryCast(chartItemwise.Series(0), LineSeries)
 
                        lineSalesChart.ItemsSource = arrSalesItems
                  Catch ex As Exception
                        HtmlPage.Window.Alert(ex.Message)
                  End Try
      End Sub
 
The above code makes an Async call to all methods from WCF. The data received from every call is put in ‘KeyValue<K.V>’ generic class. This class acts as a data source to every Chart control on the page.
Step 4: Run the application, the following result will be displayed:
SalesGrid
 
 

Conclusion: VS2010 has in built support to Silverlight 3.0. WCF 4.0 services can be consumed in Silverlight 3.0 client applications. The binary encoded WCF service can be consumed in Silverlight 3.0 client for messaging optimization.

If you liked the article,  Subscribe to the RSS Feed or Subscribe Via Email

Give me a +1 if you think it was a good article. Thanks!
Recommended Articles


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by Kevin Wade on Sunday, April 18, 2010 11:10 PM
Thanks for another good article on using .NET 4.0 with Silverlight
Comment posted by sendspace de on Wednesday, August 18, 2010 4:35 PM
WCF 4.0 is not an easy thing to understand. I am learning to work with Microsoft Visual Studio at the moment and it looks like a dark forest for me. Moreover if combine it with silverlight. Such articles as yours really help to understand many things which would be hard to come up with alone. Keep writing those articles in the nearest future too. Thanks!
Comment posted by Ilham on Thursday, January 6, 2011 1:17 AM
May I get the source code? Thank's.
Comment posted by Ilham on Monday, January 10, 2011 12:01 AM
Hey Mahesh when I'am compile in visual studio I get this error. What wrong? Thank's.

Cannot implicitly convert type 'System.Collections.ObjectModel.ObservableCollection<Silv3_StatasticsClient.MyRef.clsStatewiseSales>' to 'Silv3_StatasticsClient.MyRef.clsStatewiseSales[]'   


Cannot implicitly convert type 'System.Collections.ObjectModel.ObservableCollection<Silv3_StatasticsClient.MyRef.clsSalesData>' to 'Silv3_StatasticsClient.MyRef.clsSalesData[]'   

Cannot implicitly convert type 'System.Collections.ObjectModel.ObservableCollection<Silv3_StatasticsClient.MyRef.clsSales>' to 'Silv3_StatasticsClient.MyRef.clsSales[]'   
Comment posted by mssqldude on Wednesday, March 16, 2011 12:19 AM
Ilham - When you create the Service Reference, go into the Advanced Settings and be sure to use the System.Array collection instead of the default collection type, which is causing your error.
Comment posted by mssqldude on Wednesday, March 16, 2011 12:20 AM
This is an AWESOME example of how to bind data with Silverlight charts, using WCF. It took me a few hours to fix the code up for my Silverlight 4.0 example, but it worked out in the end. Many thanks for this!

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