Sunday, March 30, 2008

In our previous tutorial we have seen how we can use XML axis properties to consume XML returned from a web service in Silverlight applications, in this example however we will look at how XML Literals and Embedded Expressions can be used to easily write fast and efficient Web Services.

*Note XML Literals and Embedded Expression are Visual Basic 9 Exclusive features you might need Visual Studio 2008 and .NET Framework 3.5 installed.

XML Literals and Embedded Expression are not limited to Silverlight/WPF you can use it where ever you want as long as you are using Visual Basic 9 with Visual Studio 2008.

XML Literals

So, what is XML Literals? XML literals is a nice and clean way to write XML in Visual Basic, to use XML Literals "option infer" should be set "on", before we look at XML Literals, a little about literals, what are literals, for any VB.NET programmer the following code should be very familiar.

Dim Product = "Visual Basic"
Dim Version = 9
Dim SubVersion = 9.0
Dim ThisTime = #3/30/2008 3:02:00 PM#
Dim Tomarrow = #3/31/2008#

Here, I am not declaring the type of the variable, but literals allow VB to understand that Product is a string,  version is integer, subversion is double, Thistime is DataTime and Tomarrow is Date, the values that I have provided are called literals, now it should be easy to understand when I say VB 9 supports XML Literals. So instead of using quotes and escape quotes to construct XML we can simple use XML literals and just start writing XML, the following is absolutely legitimate.

Dim Products = _
<VisualStudio Version="2008">
    <Products>
        <Language Name="Visual Basic" Version="9"/>
        <Language Name="C#" Version="3"/>
    </Products>
</VisualStudio>

Yes, no more escape quote to construct XML, just start writing it there and then.

Embedded Expressions

Now, you might argue that we don't use XML inside the programs, we just need a clean way to manipulate XML not define them in our programs, but I never said we are finished with it, there is more.

In our previous example we used XDocuments/XElement/XAttribute to write XML in our web service, which can also be used to write XML in C#

This is what we had,

<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

But with Embedded Expressions and XML Literals we can make it even easier to write XML, but first what is embedded expressions, we have seen what XML literals is before and it is not very practical because we don't use XML in our program, but embedded expressions extend the user of XML Literals, embedded expressions are used to embedded values where required using <%= %> syntax.

So the previous WebMethod can be re-written using XML Literals and Embedded Expressions, but first let us find out what we are trying to write, this is the format of the XML we want to construct.

<Countries xmlns="http://tempuri.org/Schema/Countries">
    <Country Code="" Name=""/>
</Countries>

So we can replace our previous Web Service using XML Literals and embedded expression using something like,

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

        Dim sud As New CountryDataSetTableAdapters.CountryTableTableAdapter

        Dim XDataSet As New CountryDataSet.CountryTableDataTable

        sud.Fill(XDataSet)

        Dim XDoc = _
            <Countries xmlns="http://tempuri.org/Schema/Countries">
                <%= From country In XDataSet Select <Country Code=<%= country.CountryISO %> Name=<%= country.CountryName %>/> %>
            </Countries>

        Return XDoc.ToString
    End Function

Thats it! Working with XML have never been so easy, and it can't get easier than this. Enjoy the good features of VB 9. More examples coming soon.

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.

Sunday, March 16, 2008

Being a WPF developer and Silverlight enthusiast and early adopter of Silverlight I was very pleased when Microsoft employees (Tim, Scott, Jesse among others) said its going to be very close to WPF, that meant that I can reuse my WPF skills and apply them in Silverlight 2. And was waiting impatiently for Beta 1 of Silverlight 2, and when I hands on I, I was disappointed with it, I couldn't develop Silverlight applications because I was still struggling to find out what features of WPF is not in Silverlight 2.

I was going to make a lengthy report on it but I found this blog entry by Rob already there, what he did in that post was just put down a tiny-winy amount of the problems Silverlight presents over WPF, the list could go on and on. I'll try to post everything else soon.

Microsoft really need to fix these issues, otherwise we would have two versions of XAML for every instance and both of then absolutely different.

Sunday, March 09, 2008

After we heard the news of Silverlight 2.0 Beta 1 and the new "xap" architecture I blogged about why it would be better to initialise Silverlight objects independent of Silverlight DOM, but how right was I?

Here are the new test results, just be on the safe side I ran the tests on IE8 (self proclaimed better browser)

Figure 1: Browser Zoom at 100%

2008-03-09_004810

Figure 2: Browser Zoom at 75%

2008-03-09_004828

Figure 3: Browser Zoom at 50%

2008-03-09_004844

Figure 4: Browser Zoom at 125%

2008-03-09_004906 

Figure 5: Browser Zoom at 150%

2008-03-09_004926

Verdict:

Deceived by Microsoft, maybe they didn't mean to  but still there is no improvement, Silverlight is still DOM dependent, the process of initialisation is however transparent due to <object /> initialisation, this needs to be improved. I'll look deeper into this later whenever I get a chance to, but my instincts tell me that this is due the HTML access from within the managed code.

Download Source Code: 

If you know the reason please let me know, please leave your comments.

Saturday, March 08, 2008

I have been busy with my project so I haven't really got a chance to play with Silverlight 2.0 as much as I wanted to, I had a look at it but thats about it. I'll be posting XAML Resources, VB.NET/C# source code, sample, example, videos, tutorials, media player skins (I have few of them) and almost everything but I have to get my hands dirty with Silverlight 2.0 first which I'll as soon as possible.

But today you have the first instalment of Vista resources, I had them in Adobe Illustrator format for the last few months but I thought I'll give you a taste of what is coming later on, below is the image of the sample gradients, the gradients have been applied as Rectangle fills using Fill="{StaticResource BrushKey}" on gray background. Although you can use/apply them to any height the preferred height is 40, 20, 40 and 40 respectively with the image below.

2008-03-08_023916

If you don't know how to use resources here is the sample file,

But if you know how to use resources, then this is all you need

       <LinearGradientBrush x:Key="VistaWEHeader" StartPoint="0.5,1" EndPoint="0.5,0">
           <LinearGradientBrush.GradientStops>
               <GradientStop Color="#FF000000" Offset="0"/>
               <GradientStop Color="#FF9AC6CF" Offset="0.0494537"/>
               <GradientStop Color="#FF54A1AA" Offset="0.0714264"/>
               <GradientStop Color="#FF146478" Offset="0.5"/>
               <GradientStop Color="#FF408C9A" Offset="0.505493"/>
               <GradientStop Color="#FF87B6C0" Offset="0.928574"/>
               <GradientStop Color="#FFBCCDD7" Offset="0.950546"/>
               <GradientStop Color="#FFAEBFCA" Offset="0.983521"/>
               <GradientStop Color="#FFAEBFCA" Offset="1"/>
           </LinearGradientBrush.GradientStops>
       </LinearGradientBrush>

       <LinearGradientBrush x:Key="VistaStatus" StartPoint="0.5,1" EndPoint="0.5,0">
           <LinearGradientBrush.GradientStops>
               <GradientStop Color="#FF000104" Offset="0"/>
               <GradientStop Color="#FF02070B" Offset="0.494507"/>
               <GradientStop Color="#FF33373D" Offset="0.494507"/>
               <GradientStop Color="#FF757A7C" Offset="0.917587"/>
               <GradientStop Color="#FFA0A1A3" Offset="0.956039"/>
               <GradientStop Color="#FF48494A" Offset="1"/>
               </LinearGradientBrush.GradientStops>
       </LinearGradientBrush>

       <LinearGradientBrush x:Key="VistaIEHeader" StartPoint="0.5,1" EndPoint="0.5,0">
           <LinearGradientBrush.GradientStops>
               <GradientStop Color="#FFDFE4F4" Offset="0"/>
               <GradientStop Color="#FFB8BCC2" Offset="0.0439606"/>
               <GradientStop Color="#FFE0E6F4" Offset="0.0769196"/>
               <GradientStop Color="#FFD4DBE8" Offset="0.648346"/>
               <GradientStop Color="#FFE8ECF4" Offset="0.714279"/>
               <GradientStop Color="#FFFFFFFF" Offset="1"/>
           </LinearGradientBrush.GradientStops>
       </LinearGradientBrush>

       <LinearGradientBrush x:Key="VistaMenuBar" StartPoint="0.5,1" EndPoint="0.5,0">
           <LinearGradientBrush.GradientStops>
               <GradientStop Color="#FFD4D4D4" Offset="0"/>
               <GradientStop Color="#FFF0F2F4" Offset="0.0659332"/>
               <GradientStop Color="#FFF6F5F8" Offset="0.598907"/>
               <GradientStop Color="#FFFFFFFF" Offset="0.609894"/>
               <GradientStop Color="#FFFFFFFF" Offset="0.978027"/>
               <GradientStop Color="#FFC7C7C7" Offset="0.994507"/>
               <GradientStop Color="#FFC7C7C7" Offset="1"/>
           </LinearGradientBrush.GradientStops>
       </LinearGradientBrush>

Stay tuned more coming your way, and don't forget to leave your comments.

Thursday, March 06, 2008

Silverlight 2.0 Beta 1 is inconsistent with Uri Relative.

Problem:

In designing phase when you give URI relative address to MediaElement/Image or set any source from the code behind, the relative address is with the xaml/vb/cs file you are defining it in, for example, consider the following project

2008-03-06_165455

In Page.xaml if you define the source, the preview shows the image, but when the application is run it doesn't show the image

<Image x:Name="bg" Source="bg.jpg"/>

Reason:

The reason is the relative uri for the source, however the preview works but when complied the "xap" is generated in ClientBin directory, and the relative Uri will be changed to ClientBin so in run time it will look for the bg.jpg in ClientBin directory.

Solution:

Solution 1: Solution is the provide absolute Uri for the source, eg.,

<Image x:Name="bg" Source="http://website.com/bg.jpg"/>

Solution 2: Copy all your assets in ClientBin directory

Solution 3: Use absolute uri if setting from code behind eg.,

<MediaElement x:Name="ThisVideo" Height="500" />

Now set the source from code behind using Application path, in VB (take out _  and add ; at the end for C#),

VideoScreen.Source = _
 New Uri(Application.Current.Host.Source.AbsolutePath & _ 
"../../../video.wmv", UriKind.Absolute)

Please leave your comments.

 

Wednesday, March 05, 2008

Today by Hijri Calender is my birthday, and today is the day the web development has changed for the good, coincidence? perhaps symbolic?

Silverlight 2.0 Beta 1 Downloads are here

Silverlight 2.0 Beta 1 Plug in Rutime

Silverlight 2.0 Beta 1 SDK

Silverlight 2.0 Beta 1 Tools for Visual Studio 2008 (Includes SDK)

Expression Blend 2.5 March Preview

 

Overview of Libraries in Silverlight 1.1 Alpha and Silverlight 2.0 Beta 1

Silverlight 2.0 .NET Libraries

Download Chart

NOTE: This is the overview of the base libraries of .NET Framework, complete libraries may/may not be available for Silverlight 2.0

Silverlight 2.0 Beta is huge compared to Silverlight 1.1 Alpha not just in terms of including the base libraries but also in providing extra sub classes within the libraries.

For example, Silverlight 1.1 Alpha included only three sub classes for System.Security.Cryptography

  1. RNGCryptoServiceProvider
  2. CryptographicException
  3. RandomNumberGenerator

Where as Silverlight 2.0 Beta 1 includes about 20 sub classes

  1. Aes
  2. AesManaged
  3. CryptographicException
  4. CryptographicUnexpectedOperationException
  5. CryptoStream
  6. DeriveBytes
  7. HashAlgorithm
  8. HMAC
  9. HMACSHA1
  10. HMACSHA256
  11. KeyedHashAlgorithm
  12. KeySizes
  13. RandomNumberGenerator
  14. Rfc2898DeriveBytes
  15. RNGCryptoServiceProvider
  16. SHA1
  17. SHA1Managed
  18. SHA256
  19. SHA256Managed
  20. SymmetricAlgorithm
 

The party begins, Silverlight 2.0 Beta 1 Documentation is up on MSDN.