Azure Managed Disk VS AWS EBS

Recently Microsoft has added Managed Disk services to Azure Services which is a kind of reduced version as compared to Amazon Web Services (AWS) Elastic Block Store.

Some of the current limitations of Azure Managed Disk Service are

  1. Dependency on port 8443. Provisioning a VM with extensions will fail without the availability of this port. Also, the deployment status of an extension will be unknown if it is installed on a running VM. If you cannot unblock port 8443, you must use unmanaged disks
  2. Un-availability of incremental Snapshots. That means you are forced to take full disk copy, which means additional cost and more time to complete the copy.
     

Apart from these limitation below is the differential matrix between two

Feature AWS EBS Azure Managed Disk
Backup Implicit Via Azure Backup Service
Availability Auto HA across Availability Zones Auto HA within the region
Scalability Elastic Scaling limited to Storage Type gp2, io1, st1, sc1 Fixed Size. Add another disk to meet additional storage requirements.
Pricing Depends on storage type, size, & IOPS Depends on Disk Type and size.
IOPS Configurable for magnetic and io1 volume types Fixed
Encryption Via AWS Key Management Service Azure Storage Service Encryption & BitLocker
Access Via AWS Identity And Access Management Azure Role Based Access Control Service
Snapshot Both full and incremental Only full backup
Advertisements

April 24, 2017 at 1:36 pm Leave a comment

ProtocolException: The remote server returned an unexpected response: (405) Method Not Allowed.(Resolved)

ProtocolException: The remote server returned an unexpected response: (405) Method Not Allowed.(Resolved)

 

Last week I face this error while accessing the WebGet method of a restful service. Thanks to Pedrams post for providing the solution.

So here it is.

Solution

The error shows up because without creating a new context, proxy ends up using the POST verb which will eventually cause the above exception

To resolve it we need to create a new OperationContextScope everytime we make a call to a WebGet method.

Sample code:

        [ServiceContract]

        public interface ITwitterStatus

        {

            [OperationContract]

            [WebGet(UriTemplate = “/statuses/friends.xml”)]

            Message GetFriends();

        }

    public partial class _Client

    {

        protected string GetFriends()

        {

            WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);

            binding.MaxReceivedMessageSize = 99999999;

            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

            binding.Security.Transport.Realm = “Twitter API”;

            using (WebChannelFactory<ITwitterStatus> cf = new WebChannelFactory<ITwitterStatus>(binding, new Uri(“http://www.twitter.com&#8221;)))

            {

                cf.Credentials.UserName.UserName = “username”;

                cf.Credentials.UserName.Password = “password”;

                ITwitterStatus proxy = cf.CreateChannel();

                using((IDisposable)proxy)

                using (new OperationContextScope((IContextChannel)proxy))

                {

                    Message m = proxy.GetFriends();

                    return(XDocument.Load(m.GetReaderAtBodyContents()).ToString());

                }

             }

     }

May 15, 2010 at 12:21 pm 2 comments

Multi Paged Silverlight application consuming ADO.Net Data services

Multi Page Silverlight Application with ADO.NET Data Services – Insert, Update, Delete operations

This article demonstrates how to create a multiple paged Silverlight Application for Insert, Update and Deletion of data exposed by ADO.Net Data Services.

Step 1: We will first create an ADO.Net Data Services application and expose the Northwind DataBase.

Step 2: Create a Multiple Page application with the button to move Next and Previous pages.

Step 3: Orders and Order_Details table will be loaded in the DataGrid in the first page.

Step 4: Clicking “Insert” button will move to next page that will contain a blank form to insert the new row in Order or Order_Details table.

Step 1

  1. Create a new ASP.Net web site.
  2. Select to add a new item and select “ADO.Net Data Entities”.
  3. Select Data from the SQL Server and select all the Tables from Northwind database.
  4. Again add a new item and select “ADO.Net Data Services”.
  5. Expose all the Tables of Northwind database by changing the DataContext type to “NorthwindEntities” and set the config.SetEntitySetAccessRule(“*”, EntitySetRights.All)
  6. Host this web site in IIS.

Step 2

  1. Create a new Silverlight application and add an ASP.Net web site to host the Silverlight application.
  2. Select to add a new item and select new user control. Name it, Switcher.xaml.
  3. Repeat step 2 and this time provide a name, “Page2.xaml”.
  4. Open App.Xaml.VB file and in the Application startup event, change the instance from New Page1() to New Switcher();
  5. Open the Switcher.Xaml.vb file and in the initialize method, set me.content=new Page1()
  6. In the same file, add a new public method called SwitchPage which accepts UserControl as a parameter.
  7. In this method, set me.content = parameterName;
  8. Add a button to Page1.Xaml as well as Page2.xaml. In the click event of these buttons, make a call to the SwitchPage method of the Switch Class. We can get the reference of the Switch class by using Me.Parent as Switcher is the parent of both Page1 and Page2. In the SwitchPage method pass the instance of the other page.

Below is the listing of the App.Xaml.Vb Switcher.Xaml.Vb, Page1.Xaml.Vb and Page2.Xaml.Vb files

 

App.Xaml.Vb

Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup

‘Me.RootVisual = New Page()

Me.RootVisual = New Switcher()

End Sub

Switcher.Xaml.Vb

Public Sub New

        InitializeComponent()

        If Me.Content Is Nothing Then

            Me.Content = New Page1()

        End If

End Sub

Public Sub PageSwitcher(ByVal Nextpage As UserControl)

        Me.Content = Nextpage

End Sub

Page1.Xaml.Vb

Private Sub Button_Click(ByVal sender As System.Object, ByVal e As RoutedEventArgs)

        Dim swtch As Switcher = Me.Parent

        swtch.PageSwitcher(New Page2())

End Sub

Page1.Xaml.Vb

Private Sub Button_Click(ByVal sender As System.Object, ByVal e As RoutedEventArgs)

        Dim swtch As Switcher = Me.Parent

        swtch.PageSwitcher(New Page1())

End Sub

 

Step 3

  1. Open Page1.xaml and from the toolbox drag and drop the DataGrid.
  2. Set the AutoGenerateColumns of DataGrid to true.
  3. Set x:Name to GridEmployees
  4. Set ItemsSource to “{Binding}”
  5. Add a Button in the Page1.Xaml and name it btnAdd, set the content to “Add New Employee” and add a click event handler named Button_Click
  6. Open Page1.Xaml.Vb.
  7. Define a global level variable

Dim NwindService As NorthwindEntities

Dim curApp As App

  1. In the Constructor, after the InitializeComponent(), initialize the NwindService and curApp

curApp = Application.Current

NwindService = curApp.NwindService

  1. Define a DataServiceQuery to fetch the EmployeeSet

Dim dsq As DataServiceQuery(Of Employee) = From emp In NwindService.EmployeeSet Select emp

10.  Make a call to the BeginExecute method of the DataServiceQuery

dsq.BeginExecute(New AsyncCallback(AddressOf DataLoadComplete), dsq)

11.  Declare the DataLoadComplete method

Private Sub DataLoadComplete(ByVal ar As IAsyncResult)

Dim dsq As DataServiceQuery(Of Employee) = ar.AsyncState

GridEmployees.DataContext = dsq.EndExecute(ar).ToList()

            End Sub

12.  Define the Button_click event to PageSwitcher method of the Switecher class. For this, first get the reference of the Switcher class by using Me.Parent . Also generate the next employee id to be passed as a parameter to the constructor of the Page2 class.

Dim swtch As Switcher = Me.Parent

Dim emps As List(Of Employee) = CType(GridEmployees.DataContext, List(Of Employee))

Dim EmpIDs As Integer = (From id In emps Order By id.EmployeeID Select id.EmployeeID).Last()

swtch.PageSwitcher(New Page2(EmpIDs + 1))

13.  Open Page2.Xaml and place the 4 TextBlock and 4 TextBoxes for EmployeeId, FirstName, LastName and Country. Place a button and attach a click event.

14.  Open the Page2.Xaml.Vb. Declare the global label variables NwindService and curApp similar to  Page.Xaml.Vb and declare a new constructor that takes NewEmployeeId as Integer as parameter.

Public Sub New(ByVal NewEmpId As Integer)

InitializeComponent()

TxtEmploeeID.Text = NewEmpId.ToString()

curApp = Application.Current

NwindService = curApp.NwindService

End Sub

15.  In the Button’s click event define the code to call the AddToEmloyeeSet method of the NwindService and call the BeginSaveChanges method.

Private Sub AddEmp_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

NwindService.AddToEmployeeSet( _

New Employee() With {.EmployeeID = TxtEmploeeID.Text, _

.FirstName = TxtFirstName.Text, _

.LastName = TxtLastName.Text, _

.Country = TxtCountry.Text})

NwindService.BeginSaveChanges(New AsyncCallback(AddressOf Employee_added), Nothing)

End Sub

16.  Define the Employee_added method and call the EndSaveChanges method of the NwindService in the try catch block. Finally make a call to the PageSwitcher method of the Switcher class to go back to Page1

Public Sub Employee_added(ByVal res As IAsyncResult)

Try

NwindService.EndSaveChanges(res)

Catch ex As Exception

End Try

Dim swtch As Switcher = Me.Parent

swtch.PageSwitcher(New Page())

    End Sub

June 8, 2009 at 4:35 pm Leave a comment

ADO.Net DataServices and Silverlight

This post describes the complete steps to create an ADO.Net DataServices exposing the SQL Data, using Visual Studio 2008 Professional version and also describes the steps to be taken to create a Silverlight client application to access the data exposed by ADO.Net Data Services.  In case, if you’ve got any specific requirement, please feel free to write to me at HarishSuhanda@Gmail.com

Creating the ADO.Net Data Services to expose the PUBS database.

  1. Open VS2008 and select a ASP.Net Web Site, name it “PubsADOService”.
  2. Remove the Default.Aspx that is already added in the project.
  3. Right click on the web site in the “Solution Explorer” and select “Add New Item”.
  4. Select “ADO.Net Entity Data Model”. Name it, Pubs.edmx
  5. Click “Yes” to place the code in “ASP_Code” folder.
  6. Select “Generate from DataBase”, click “Next”.
  7. Select/create the Connection.
  8. Clik “Next”.
  9. Select the Name of the Tables that you want to expose via ADO.Net Data Service. For this demo select all the tables.

10.  Rename the Entity Set Names of all the tables by adding “Set”. Thus, the entitis name and Entity Set Name should be,  Titles and TitlesSet, author and authorSet like wise…

11.  Click “Save All”.

12.  Open the Solution Explorer and repeat step 3 to add “New Item”.

13.  Select “Ado.Net Data Service”. Name it “PubsDataService.svc”. Click “Add” button.

14.  In the “PubsDataService.svc.vb” or “PubsDataService.svc.cs”, whichever application (.vb is for Visual Basic and .cs is for C#). Replace the code,

Inherits DataService(Of [[class name]])

With

Inherits DataService(Of pubsModel.pubsEntities)

15.  In the InitializeService method, un comment the code to SetEntityAccessRule. (By default all the entities defined in the EntitiyModel has restrictsions. The will be blocked by default unless the EntitiyAccessRule is not defined)

16.  Replace “MyEntitySet” with the name of the entityset that you want to expose. To expose all the entities, set

config.SetEntitySetAccessRule(“*”, EntitySetRights.All)

17.  Click “Save All”. Now the PubsDataService is avalable to be hosted.

18.  Run the PubsDataService web site.

Create the Silverlight client to access the PubsDataService created above.

  1. Create a new Silverlight project in VS2008. Name it, “Client_PubsDataService”.
  2. Click “Yes” to add an asp.net project to host the Silverlight application.
  3. Right click on the Client_PubsDataService in the solution explorer and select “Add Service Reference….”.
  4. Switch to PubsDataService created in above steps and run it.
  5. Copy the URL of the PubsDataService.svc file, which is something like (except the port number will be different) http://localhost:49165/PubsADOService/PubsDataService.svc/
  6. Keep this application running and switch to “Client_PubsDataService” application.
  7. Pate the copied URL in the “Address” field of the “Add Service Reference….” Dialog box and click “Go”.
  8. The “PubsDataService” will be identified and on expanding it, you will see all the entities that are exposed by the service.
  9. Change the name of the service to “PubsServiceReference” and click “OK”

10.  Open Page.xaml and add a ComboBox to the “LayoutGrid”.

11.  Add 2 Rows to grid, using

      <Grid.RowDefinitions>

            <RowDefinition/>

            <RowDefinition/>

</Grid.RowDefinitions>

12.  Place a “DataGrid” from toolbox below the ComboBox.

13.  Assign a name to the ComboBox, bind the itemssource and attach the SelectionChanged event. <ComboBox x:Name=”lstEntities” ItemsSource=”{Binding}” SelectionChanged=”lstEntities_SelectionChanged”></ComboBox>

14.  Assign a name to the DataGrid and bind the itemssource property. <data:DataGrid x:Name=”GridDisplayData” Grid.Row=”1″ ItemsSource=”{Binding}”></data:DataGrid>

15.  Switch to code view of the Page.Xaml. Define a global variable named “PubsService” of type PubsServiceReference.pubsEntities

16.  In the constructor, after the InitializeComponents method, initialize the PubsService by passing the Uri object. The Uri object should be created using two parameters, the url of the PubsDataService ie, http://localhost:49165/PubsADOService/PubsDataService.svc/ and Uri type which is Absolute.

17.  Add the name of the entities to the lstEntities that you disposed via the Service. Using lstEntities.Items.Add(“SalesSet”), lstEntities.Items.Add(“StoreSet”) like wise all the entities.

18.  In the lstEntities_SelectionChanged event, put a Select Case statement, Select Case lstEntities.SelectedIndex. For each selectedIndes write the code to fetch the data from the EntitySet using the code below:

Like for Authors:

            Case 1

                Dim dsq As System.Data.Services.Client.DataServiceQuery(Of PubsServiceReference.author)

                dsq = CType(PubsService.authorSet, System.Data.Services.Client.DataServiceQuery(Of PubsServiceReference.author))

                dsq.BeginExecute(New AsyncCallback(AddressOf Authors_LoadComplete), dsq)

  1. Define the Authors_LoadComplete event using following code and bind the result to the Grid.

 

    Private Sub Authors_LoadComplete(ByVal ar As IAsyncResult)

        Dim qry As System.Data.Services.Client.DataServiceQuery(Of PubsServiceReference.author) = _

        CType(ar.AsyncState, System.Data.Services.Client.DataServiceQuery(Of PubsServiceReference.author))

        Dim Authors = qry.EndExecute(ar).ToList

        GridDisplayData.DataContext = Authors

        GridDisplayData.AutoGenerateColumns = True

    End Sub

 

OutPut:

 ADO_Output

June 1, 2009 at 6:54 pm 1 comment

Accessing ScriptableType objects of Silverlight from JavaScript

 This post describes, how to access the custom objects defined in Silverlight via Javascript. It also shows how to access the content of Silverlight TextBox from Javascript.

 Creating a ScriptableType object in Silverlight Application

The ScriptableType attribute and ScriptableMember attribute defined in the System.Windows.Browser interface is used to make an object available to the client side.

Thus, we will declare a Person class with two properties, FName and LName and implement the INotifyPropertyChanged Interface so that the changes made to these properties can be reflected to all the objects that are accessing it.

Use the below code to define the Person Class.

Imports System.Windows.Browser

<ScriptableType()> _

Public Class Person

    Implements System.ComponentModel.INotifyPropertyChanged

    Public Sub New()

    End Sub

    Private Sub PropertyChangedCaller(ByVal PropertyName As String)

        RaiseEvent PropertyChanged(Me, New ComponentModel.PropertyChangedEventArgs(PropertyName))

    End Sub

    Private _FName As String

    <ScriptableMember()> _

    Public Property FName() As String

        Get

            Return _FName

        End Get

        Set(ByVal value As String)

            _FName = value

            PropertyChangedCaller(“FName”)

        End Set

    End Property

    Private _LName As String

    <ScriptableMember()> _

    Public Property LName() As String

        Get

            Return _LName

        End Get

        Set(ByVal value As String)

            _LName = value

            PropertyChangedCaller(“LName”)

        End Set

    End Property

 

    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

End Class

 

Creating Person Object in XAML and Binding the values to Silverlight TextBox controls

We will now create the object of Person class under the UserControl.Resources, declared above and then bind it to the TextBoxes. Use the following code for the same:

<UserControl.Resources>

<local:Person x:Name=”PersonObject” FName=”FirstName” LName=”LastName” />

</UserControl.Resources>

 

Use the code below to create the grid with text boxes and labels and bind them to above created resources:

<Grid x:Name=”LayoutRoot” Background=”White” DataContext=”{StaticResource PersonObject}”>

<Grid.ColumnDefinitions>

<ColumnDefinition/><ColumnDefinition/>

</Grid.ColumnDefinitions>

<Grid.RowDefinitions>

     <RowDefinition/><RowDefinition/><RowDefinition/>

</Grid.RowDefinitions>

<TextBlock Grid.Column=”0″ Grid.Row=”0″ Text=”First Name:”/>

<TextBlock Grid.Column=”0″ Grid.Row=”1″ Text=”Last Name:”/>

<TextBox Grid.Row=”0″ Grid.Column=”1″ Text=”{Binding FName, Mode=TwoWay}” />

<TextBox Grid.Row=”1″ Grid.Column=”1″ Text=”{Binding LName, Mode=TwoWay}” />

<TextBlock Text=”{Binding FName}” Grid.Row=”2″ Grid.Column=”0″/>

<TextBlock Text=”{Binding LName}” Grid.Row=”2″ Grid.Column=”1″/>

</Grid>

Registering the Person Object

To make the PersonObject available to clientside, we need to register the object, using the Browser.HtmlPage.RegisterScriptableObject. We may do this in the Page_Loaded event of the Silverlight application:

Private Sub Page_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

‘Access the PersonObject defined under the UserControl.Resources

Dim personObject As Person = Me.Resources(“PersonObject”)

        Browser.HtmlPage.RegisterScriptableObject(“PersonObject”, personObject)

End Sub

 

Accessing the PersonObject from JavaScript

The PersonObject created above is now ready to be accessed from the JavaScript. Create a variable referencing the SilverlightPlugin in the ASPX Page. Next, access the Content of the SilverlightPlugin using the Content property. Finally, access the PersonObject from the Content of the SilverlightPlugin

            var silverlightplugin = $get(“Xaml1”);

            var content = silverlightplugin.content;

            var personObject = content.PersonObject;

 

Using the personObject, we may access it public properties. Thus,

alert(“Name = ” + personObject.FName + ” ” + personObject.LName);

 

will show the current content from the TextBoxes in the Silverlight TextBoxes as displayed below:

Output

May 28, 2009 at 10:56 pm Leave a comment

Sending Objects from .ASPX page to Silverlight

Sending Simple User Defined Objects from ASPX page to Silverlight Application.

This article describes how to send a user defined object created in ASP.Net application across Silverlight application. We will walk though creating a Simple User Defined object in ASPX page called Person and another object called People containing the list of Person.

We will use XMLSerializer to serialize the People class and add the xml content to the InitParametes of the <ASP:Silverlight /> object.

We will then extract the xml from InitParameters in the StartUp_Application event of the Silverlight and fill the data back in the People Class defined in Silverlight application as well.

Creating ASP.Net application to create a list of CustomObject

  1. Create a Silverlight application and choose ASP.Net Web Site to host the Silverlight application.
  2. Open the ProjectName.Web project and open the Silverlight test page.
  3. Add a server tag in the .aspx page and add the code to define the Person.
  4. Mark the class Serializable.
  5. Create another class People which contains the list of Person.
  6. Mark this class as Serializable too.
  7. Create an object of People and add the Person to list of Person.

    <Serializable()> _

 Public Class Person

Implements System.ComponentModel.INotifyPropertyChanged

Public Sub New()

End Sub

Private Sub NotifyPropertyChanged(ByVal info As String)

            RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(info))

 End Sub

Private _FirstName As String

Public Property FirstName() As String

            Get

                Return _FirstName

            End Get

            Set(ByVal value As String)

                _FirstName = value

                NotifyPropertyChanged(“FirstName”)

            End Set

        End Property

 

        Private _LastName As String

        Public Property LastName() As String

            Get

                Return _LastName

            End Get

            Set(ByVal value As String)

                _LastName = value

                NotifyPropertyChanged(“LastName”)

            End Set

        End Property

 

        Private _Age As Integer

        Public Property Age() As Integer

            Get

                Return _Age

            End Get

            Set(ByVal value As Integer)

                _Age = value

                NotifyPropertyChanged(“Age”)

            End Set

        End Property

Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

    End Class

 

    <Serializable()> _

    Public Class People

        Private _Persons As System.Collections.Generic.List(Of Person)

        Public Sub New()

            Persons = New System.Collections.Generic.List(Of Person)

        End Sub

        Public Property Persons() As System.Collections.Generic.List(Of Person)

            Get

                Return _Persons

            End Get

            Set(ByVal value As System.Collections.Generic.List(Of Person))

                _Persons = value

            End Set

        End Property

    End Class

Serializing the list of CustomObject and setting it to InitParameters

  1. Serialize it using XMLSerializer.
  2. Using the StringWriter class, write the serialized string to a Serialized variable.
  3. Set the InitParameters of Silverlight object to “People=” + StringWriterObject.ToString

        Dim xmlFrmtr As New System.Xml.Serialization.XmlSerializer(ppl.GetType)

        Dim txtWrt As New System.IO.StringWriter()

        xmlFrmtr.Serialize(txtWrt, ppl)

        Xaml1.InitParameters = “People=” + txtWrt.ToString

Accessing the InitParameters in the Silverlight application.

  1. Open the Silverlight application and open the App.Xaml.Vb file
  2. In the App Class, add a public property called InitParams as Dictionary of string, string.
  3. In the Application_Startup event set the InitParams equal to e.InitParams
  4. In the Page_Loaded event of Siliverlight in “Page.Xaml.Vb”, create an instance of Application class and assign Application.Current to it.
  5. Create a StringReader and read all the content of People, which is a XML document.
  6. Use the XML Reader to read the xml from the String Reader.
  7. Extract the values from XmlReader and parse it into the People/Person class defined in the Silverlight Application.

        Dim app As App = Application.Current

        Dim xrDr As XmlReader = XmlReader.Create(New System.IO.StringReader(app.InitParams(“People”)))

        Dim ppl As New People()

         While xrDr.Read()

            If xrDr.IsStartElement And xrDr.Name = “Person” Then

                Dim prsn As New Person()

                xrDr.ReadToFollowing(“FirstName”)

                prsn.FirstName = xrDr.ReadElementContentAsString()

                xrDr.ReadToFollowing(“LastName”)

                prsn.LastName = xrDr.ReadElementContentAsString()

                xrDr.ReadToFollowing(“Age”)

                prsn.Age = xrDr.ReadElementContentAsInt

                ppl.Persons.Add(prsn)

            End If

        End While

May 28, 2009 at 10:55 pm Leave a comment

Silverlight2.0 Nested DataGrid using Silverlight-enabled WCF Services and LINQ to SQL

Create new project.

  1. Create a new Silverlight project in Visual Studio 2008 or Visual Web Developer 2008 and select a new Web Site to host the Silverlight application. Name it “Silverlight_MasterDetailsGrid”
  2. When the IDE opens, we have 2 projects listed. Silverlight_MasterDetailsGrid and Silverlight_MasterDetailsGrid.Web. The Web application has a Silverlight_MasterDetailsGrid.TestPage.aspx which hosts the .zap file created by Silverlight_MasterDetailsGrid.

Add Linq to SQL Classes

  1. Select Silverlight_MasterDetailsGrid.Web project in Solution Explorer and right click to add new item.
  2. Select “LINQ to SQL Classes”.
  3. Name the File to “Nwind.dbml”  and click OK
  4. Drag and Drop the Orders and Order_Details table from Server Explorer.
  5. Right click on any blank space in Nwind.dbml file and select “Properties”.
  6. Set SerializationMode to “Unidirectional”. [Currently, WCF does not support Cyclic Reference Serialization (like in dbml file the Order Table contains a Order_Detail filed and Order_Detail Table contains the Order field. Setting the SerializationMode to Unidirectional will serialize only tables excluding the referential table/fields)
  7. Click Save. [The Nwind.Designer.VB file will have all the classes with the DataContract attribute applied to Order and Order_Detail tables and DataMember attribute to the properties of these tables. This will make these classes serializable thus ready to be used in WCF Services]

Add WCF Service.

  1. Select Silverlight_MasterDetailsGrid.Web project in Solution Explorer and right click to add new item.
  2. Select “Silverlight-enabled WCF Service”
  3. Name the file “WCFService.svc” and click “OK”
  4. The Visual Studio will open the WCFService.svc.vb file with a class with dummy Service Contract and Operation Contract.
  5. Click “Project” menu and select “Add New Item”.
  6. Select Interface and Name it “IWCFService.vb”. Click “OK”
  7. Imports two Interfaces, System.ServiceModel and System.ServiceModel.Activation
  8. Add ServiceContract attribute to IWCFService Interface and define two OperationContracts GetOrders and GetAllOrderDetails. Thus the IWCFService.vb should look like:
Imports System.ServiceModelImports System.ServiceModel.Activation<ServiceContract()> _

Public Interface IWCFService

<OperationContract()> _

Function GetOrders() As IEnumerable(Of Order)

<OperationContract()> _

Function GetAllOrderDetails() As IEnumerable(Of Order_Detail)

End Interface

 9.  Open WCFService.svc.vb and delete all content of the Class and its ServiceContract attribute.

10.  Implement IWCFService Interface in the WCFService Class. This class will have only one attribute [AspNetCompatibilityRequirements].

11.  Implement the GetOrders and GetAllOrderDetails functions

12.  The WCFService.svc.vb should now look like:

Imports System.ServiceModelImports System.ServiceModel.Activation<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> _

Public Class WCFService

    Implements IWCFService

    Public Function GetOrders() As IEnumerable(Of Order) Implements IWCFService.GetOrders

        Dim DC As New NwindDataContext()

        Return DC.Orders.AsEnumerable()

    End Function

 Public Function GetAllOrderDetails() As IEnumerable(Of Order_Detail) Implements IWCFService.GetAllOrderDetails

        Dim DC As New NwindDataContext()

        Return DC.Order_Details.AsEnumerable

    End Function

End Class

13.  Open Web.Config file and change the Contract in Endpoint section from Silverlight_MasterDetailsGrid.Web.WCFService to Silverlight_MasterDetailsGrid.Web.IWCFService

 This finalizes our WCF service and makes it ready to be hosted.

Defining the Service Reference in client to consume the above created WCFService

  1. In the Solution Explorer, expand the “Silverlight_MasterDetailsGrid” project. Right click on it and click “Add Service Reference”.
  2. Click “Discover” to locate the WCFService automatically.
  3. Name the Service “NwindWcfReference”

Adding DataGrid to Silverlight application

  1. Open Page.xaml and drag and drop the DataGrid from ToolBox to the Code window, under LayoutRoot grid.
  2. Name the DataGrid by adding x:Name attribute to “GrdOrders”.
  3. Set AutoGenerateColumns to True.
  4. Set ItemsSource to “{Binding}”. This will bind the DataGrid to its DataContext.

Thus, the DataGrid definition should look like:

<data:DataGrid x:Name=”GrdOrders” AutoGenerateColumns=”True” ItemsSource=”{Binding}”/>

Binding GrdOrders DataGrid to Orders

  1. Open Page.xaml.vb.
  2. Imports Silverlight_MasterDetailsGrid.NwindWcfReference
  3. Imports System.Collections.ObjectModel
  4. Add a class level variable Orders of type ObservableCollection(Of Order)
  5. Add another class level variable wcfClient of type WCFServiceClient
  6. In the constructor initialize the Orders and wcfClient variables after InitializeComponent()
  7. In the Page_Loaded event add the event handler to the wcfClient, using AddHandler WcfClient.GetOrdersCompleted, AddressOf GetOrdersCompleted
  8. Call the WcfClient.GetOrdersAsync() method
  9. Define the GetOrdersCompleted method Public Sub GetOrdersCompleted(ByVal sender As Object, ByVal e As GetOrdersCompletedEventArgs)
  10. Set Orders = e.Result
  11. Set GrdOrders.DataContext = Orders

Run the application and see the all records with all the columns of Orders table are displayed in the DataGrid.

Defining RowDetailsTemplate to create nested DataGrid

  1. Open the Page.xaml and add the RowDetailsTemplate to GrdOrders.
  2. Define the DataTemplate.
  3. Add DataGrid to DataTemplate and name it GrdDetails.
  4. Set it’s AutoGenerateColumn property to “True”

Thus the resulting XAML of Complete DataGrid should look like:

<data:DataGrid x:Name=”GrdOrders” AutoGenerateColumns=”True” ItemsSource=”{Binding}”>

<data:DataGrid.RowDetailsTemplate>

<DataTemplate>

<data:DataGrid x:Name=”GrdDetails” AutoGenerateColumns=”True” ItemsSource=”{Binding Order_Details}”></data:DataGrid>

</DataTemplate>

</data:DataGrid.RowDetailsTemplate>

</data:DataGrid>

Calling the GetAllOrderDetailsAsync and binding the inner DataGrid to Order_Detail

  1. Add another class level variable allOrder_Detais of type ObservableCollection(Of Order_Detail)
  2. In the Page_Loaded event, add the WcfClient.GetAllOrderDetailsCompleted handler.
  3. In the GetOrdersCompleted event, make a call to WcfClient.GetAllOrderDetailsAsync()
  4. Define the GetAllOrderDetailsCompleted and add following code that
    1. Fetches all the rows and columns of the Order_Details table and store it in allOrder_Detais variable.
    2. Loop through all the Order in Orders and using LINQ query find all the OrderDetails from allOrder_Detais whose OrderId is equal to Order.OrderID
    3. Create a temporary ObservalbleCollection(of Order_Detail) and insert items of Order_Detail fetched in steps b.
    4. Assign the temporary collection created in steps c to Order.Order_Details
    5. Set the GrdOrders.DataContext to Orders

The resulting GetAllOrderDetailsCompleted function should be:

Public Sub GetAllOrderDetailsCompleted(ByVal sender As Object, ByVal e As GetAllOrderDetailsCompletedEventArgs)

allOrder_Detais = e.Result

For Each o As Order In Orders

Dim tempOrder_Details = From allDetails In allOrder_Detais Where allDetails.OrderID = o.OrderID Select allDetails

Dim tempDetails As New ObservableCollection(Of Order_Detail)

For Each item In tempOrder_Details

tempDetails.Add(item)

Next

o.Order_Details = tempDetails

Next

GrdOrders.DataContext = Orders

End Sub

OUTPUT: Click any row of Master DataGrid to display the related OrderDetails in nested DataGrid.

SilverlightNestedDataGrid

May 13, 2009 at 7:39 pm 2 comments


Recent Posts