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.
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..."
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",
This will add a new database to the Web Application, go to server explorer and select, and in Tables, select "Add New Table"
Now define the table, I have inserted only two columns for this example
Now I have manually inserted rows in the table,
Step 2: Retrieving data from Database to DataSet.
Now go to the web site project and add new item,
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".
Now you'll have an empty DataSet in the solution.
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.

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".
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"
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.
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)

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.
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.
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.
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.
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.

Now we are ready to do use VB Literals, simply declare a variable without any type declaration (Type Infer)
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.
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)
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>)
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.
So the complete code looks something like,
More on VB Literals and the wonders we can do in Silverlight coming soon.