Tuesday, March 25, 2008

There might be a few samples of working with web services in Silverlight but I promise I'll keep you interested with VB.NET exclusive feature VB Literals. This is going to open a whole new way of looking and working with XML and Web Services. 

*Note: Don't attempt to do everything I do in this tutorial in C# (espcially consuming WebService in Silverlight 2) because you simply can't, C# or any other language doesn't have this feature, so stick to VB.NET for consuming you can use C# for the rest, I'll warn when I am using VB.NET exclusive features, so if you want to convert this to C# you'll get enough warning.

In this tutorial we'll look at

  • Creating SQL Server 2005 Database
  • Retrieving Data from Database in DataSet
  • Consuming DataSet in ASMX WebService (using LINQ)
  • Consuming WebService in Silverlight 2 (using VB Literals)

Before you get started with this make sure you have installed

  • Visual Studio 2008
  • SQL Express 2005
  • Silverlight 2 Beta 1 Tools for Visual Studio

Before anything start with a Silverlight project, and make sure you select Web Solution for hosting, instead of HTML Test Page.

2008-03-25_014305 2008-03-25_014320

Step 1 : Creating SQL Server 2005 Database

Now we'll create a SQL Server and add data in the database, for this example I have used countries example, so first go to the web project, select the "App_Data" folder and right-click and select "Add New Item..."

2008-03-25_014611

Now Visual Studio will ask you the item you want, select "SQL Server Database", give a name to the database and then select select "Add",

2008-03-25_014637

This will add a new database to the Web Application, go to server explorer and select, and in Tables, select "Add New Table"

 2008-03-25_014702

Now define the table, I have inserted only two columns for this example

2008-03-25_014759 2008-03-25_014838

Now I have manually inserted rows in the table,

2008-03-25_015552 

Step 2: Retrieving data from Database to DataSet.

Now go to the web site project and add new item,

2008-03-25_015649

When the window pops up select "DataSet", select the file name I have used "CountryDataSet.xsd", Visual Studio will warn you that DataSet should go in "App_Code" Folder, select "Yes".

2008-03-25_015709 2008-03-25_015725

Now you'll have an empty DataSet in the solution.

2008-03-25_015742

Normally developers do this the "Old School" way, by setting the connections to the database, this way it will automatically make the connection string and generate datasets.

Now the trick to get data in Dataset is the most simplest way to do it.

Drag the table you want to add to DataSet space, if you have more than one table don't worry just drag all the tables you want in that dataset, if there are connections it will automatically set them all.

2008-03-25_015835

By default, the DataSet makes Fill,GetData table adapters, if you want to insert or update the tables you have to write new queries on the Table Adaptors.

Now your data is ready to be consumed by the webservice.

Step 3: Consuming DataSet in ASMX web service (Using LINQ)

Again go to the Web Site Solution and select "Add New Item..." this time select "Web Service".

2008-03-25_015913 

By default, the application makes Hello World example, delete that and add a new function.

But first, set the reference of the web service to "System.XML.Linq", Normally we use web services to communicate in XML format, but since Silverlight doesn't support "System.Data" it is not possible to return DataSet in XML format directly (if you attempt to return a DataSet directly Silverlight will throw errors when a reference is added) so we have to create our own XML String, so and we are going to use LINQ (Language Integrated Query) which is available in .NET Framework 3.0/3.5.

<WebMethod()> _
    Public Function AllCountries() As String

        Dim sud As New CountryDataSetTableAdapters.CountryTableTableAdapter

        Dim XDataSet As New CountryDataSet.CountryTableDataTable

        sud.Fill(XDataSet)

        Dim MyNameSpace As XNamespace = "http://tempuri.org/Schema/Countries/"

        Dim XDoc As XDocument = New XDocument(New XDeclaration("1.0", "utf-8", "yes"), _
                                              New XElement(MyNameSpace + "Countries", _
                                                        From country In XDataSet _
                                                        Select New XElement("Country", _
                                                                            New XAttribute("Code", country.CountryISO), _
                                                                            New XAttribute("Name", country.CountryName))))

        Return XDoc.ToString
    End Function

The Namespace is not required but it would be required to use VB literals when we are consuming this in Silverlight application.

Step 4: Consuming Web Service in Silverlight 2 (Using VB Literals)

Now we are finished with working on the web site project, and we will turn our focus on the Silverlight Project.

First we'll add the "Web Reference"

2008-03-25_022423

Since the Web Services is in the same solution, you can just click "Discover" and it will fetch the web service, give a namespace to the web service to easily recognise within the application.

2008-03-25_022517 2008-03-25_022536

In Silverlight projects System.Xml.Linq is not automatically selected so you have to explicitly include it, right click on the Silverlight Project and then Select "Add Reference", and add reference to System.Xml.Linq, even after you have added reference you still have to import it in the managed code (VB imports System.Xml.Linq/ include System.Xml.Linq)

2008-03-25_022642

Now we have to call the web service from Managed code.

Imports System.Xml.Linq

Partial Public Class Page
    Inherits UserControl

    Public Sub New()
        InitializeComponent()
    End Sub

    Private src As New CountryWebService.WebServiceSoapClient
    Private XMLData As New XDocument

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

        src.AllCountriesAsync()
        AddHandler src.AllCountriesCompleted, AddressOf DownloadCompleted
    End Sub

    Private Sub DownloadCompleted(ByVal sender As Object, ByVal e As CountryWebService.AllCountriesCompletedEventArgs)

        XMLData = XDocument.Parse(e.Result)

    End Sub
End Class

Now you can set a break point on XMLData = XDocument.Parse(e.Result)  and test the XML we are getting back.

2008-03-25_023106

As we have XML Data available, normally we create a class object, initialise properties are pick each attribute of the XMLData and populate its property, this is the only way to do in C# but for VB.NET there is very simple way. 

*WARNING: VB Exclusive feature below*

In VB.NET we have an exclusive feature, called VB Literals, VB literals is a new feature in .NET framework 3.0, which makes life easy infact very easy, this is an extension of type infer available since early VB days, to use this option "Option Infer" should be set "On".

You can google for "VB Literals" for more info, I won't go in details here so I'll just go directly to the point.

Type infer means that we don't need to set the type while variable declaration, and this is an essential for VB Literals to work hence not included in C# or any other .NET languages.

But for this example, since we are working on XML and to enable Intellisense we would require to get the schema of the XML we would be working on, this is not essential but without it there won't be any Intellisense.

So first we'll get the schema for the XML we got back, to do this we'll set the breakpoint again and get the XML data from XMLData XDocument we are getting back from the webservice.

2008-03-25_023205

Next we'll add a schema file by "Add New Item..." in the Silverlight project, there is a Template "XML to Schema" for this available on MSDN. The Name of the schema doesn't matter here, because we won't be looking at it ever, Visual Studio will do its own magic.

2008-03-25_023255

Now since we already have the data copied in the clipboard, we'll select Add As XML and paste the copied XML to generate Schema.

2008-03-25_023307 2008-03-25_023326

Now we have to import the schema by Adding the reference, Visual Studio will automatically recognises the namespace available in the project, all we have to do is provide the alias. 

2008-03-25_023400   2008-03-25_023415

Now we are ready to do use VB Literals, simply declare a variable without any type declaration (Type Infer)

2008-03-25_023606

Visual Studio recognises the the data we are dealing with and started to help, without creating schema and importing we can still use VB Literals but there won't be any intellisense.

2008-03-25_023621

Visual Studio recognises the Elements but don't know where you want to start digging the XML so its showing "?" But once you select the starting Element, it will know where you are and what you are dealing with so now it is showing the "Right Mark", it is its way of saying you are definitely dealing with this. the options are "@" for attribute, "<>" for any Child Element (NOTE: If you are using Element, then you should get its value e.g., i.<ElementName>.Value)

2008-03-25_023726

After you finish writing your query, something wonderful happens, if you add only one single element the Type Inference selects the data as IEnumerable(Of String) but if you add more than one to the collection it will automatically change to IEnumerable(Of <anonymous type>)

2008-03-25_024200

2008-03-25_024214

To consume this data in Silverlight application you can use them directly.

In Page.xaml

<Grid x:Name="LayoutRoot" Background="White">
    <ListBox x:Name="CountryNames"/>
</Grid>

In Page.xaml.vb

CountryNames.ItemsSource = CountriesData

And when you run the application.

2008-03-25_024023

So the complete code looks something like,

2008-03-25_044631

More on VB Literals and the wonders we can do in Silverlight coming soon.

 

I have been very busy lately with different projects and now I have a little bit of time on my hands to play around with Silverlight 2. As I have promised before loads of Tutorials are coming your way. So stay tuned.

I am little late in blogging, so there are many tutorials already available, so I'll cut the long way and come directly to doing complex things in Silverlight, so if you are expecting "Hello World" in Silverlight then look else where.

I will be posting tutorials in VB.NET, and if possible I'll also post C# code, but since Silverlight 2 now supports System.XML.Linq, I will also be using VB Literals which is VB exclusive, so even if you are C# programmer you don't want to miss that, just don't blame me if you start loving VB.NET more than C#, which I bet you will.