Adopting Silverlight - An Architects Point of View

Abstract

A very common deployment scenario for Silverlight 1.1 Applications is to be hosted from Windows Server 2003/IIS6 environments. This implies that the development environment for Silverlight will be based in .Net Framework 3.5 while the deployment environment will be based in .Net Framework 2.0. Combine the platform mismatch between development and production environments with the fact that we are working with as yet unsupported products and technology and we have a recipe for a failed project. We would be introducing risk into our project. That risk that must be understood and mitigated for if we plan on being early adopters of this breakthrough technology. This article delves into the areas of risk associated with developing Silverlight 1.1 applications that invoke Web Services and that are then deployed into Windows Server 2003/IIS6 environments.

Introduction

Silverlight is a cross platform, cross browser plug-in for creating Rich Internet Applications, Silverlight supports a subset of Windows Presentation Foundation XAML combined with a code behind model to produce stunning visual experiences that leverage vector graphics, animation, streaming video and rich user interface controls.

Since Silverlight applications run in the browser and since browsers support web services it make sense to leverage web services for data access. Combining Silverlight with web services has the same architectural underpinnings as AJAX; client side code asynchronously invoking web services via the XmlHttpObject.

Silverlight comes in 2 versions today:

  • Silverlight 1.0 (beta) – Uses XAML for defining the user interface combined with code behind in the form of Javascript scripts
  • Silverlight 1.1 (alpha) – Uses XAML for defining the user interface combined with C#, VB, Ruby or Python in the code behind

Web Services that you wish to call from Silverlight applications are also required to be marked scriptable. By marking the service scriptable, you have control over the response format, which can be either Xml or JavaScript Object Notation (JSON). One of the advantages of using JSON as a serialization format over XML is that you can deserialize objects by simply evaluating a JSON string. This is especially useful when returning objects or collections of objects from web service calls.

Calling Web Services from Silverlight 1.0 leverages exactly the same approach as an AJAX Application. Simply use your favorite AJAX library (ASP.Net AJAX for example) to configure the service proxy references and invoke the services asynchronously. This is all done from client side JavaScript. Since this is a technique that is well documented I will not cover it in detail here. Refer to the ASP.Net AJAX (https://ajax.asp.net) web site.

Instead I intend to focus on developing Silverlight 1.1 applications that invoke Web Services directly. My development environment will leverage Visual Studio 2008 Beta 2 and be based on .Net Framework 3.5. I will then cover deploying both the Silverlight application and the Web Service to a Windows Server 2003 .Net Framework 2.0 environment. This configuration is shown here:

image

                                  Common Silverlight 1.1 Architecture Pattern

I believe that this will be a very common configuration for some time and since doing this is not as straight forward today due to the early release bits we are dealing with, I wanted to document the process I have discovered for both developing and deploying applications that leverage this configuration. There is no doubt the Visual Studio and Silverlight teams will smooth out many of these issues by release time but if you want to start working with alpha and beta bits in a production environment having the process well documented should make adoption go much smoother.

The tricky part of this approach has to do with the fact that your development environment will be configured for .Net Framework 3.5 and the host production environment will be configured for .Net Framework 2.0. In addition, Silverlight at this time does not support cross domain scripting so you will need to avoid that in both your development and production environments.

If you want to follow the tutorial section of the article you will need the following system setup:

Development Client

Production Server

  • Windows Server 2003 w/ IIS6

<ShamelessPlug> I use Discount ASP (https://www.discountasp.com) for my hosting needs. They are awesome and I highly recommend them. </ShamelessPlug>

Solution Setup for a Silverlight 1.1 Application with Web Services

In this section I will cover the step by step recipe for creating a Silverlight 1.1 Application that invokes web services. The resulting configuration will allow for seamless debugging of the both the client side Silverlight code as well as the server-side web service code.

Step 1: Create an empty Visual Studio Solution using Visual Studio 2008 Beta 2

File, New, Project, Other Project Types

image

  • Call it ‘SilverlightAndWebServicesSolution’
Step 2: Add a Silverlight Project into the Solution

This will be the Silverlight Client project.

File, Add, New Project

image

  • Call it ‘SilverlightApp’
Step 3: Add a TextBlock element to the XAML

This will be the placeholder for the data returned by our web service.

image

Give the TextBlock the name ‘TheMessage’. The TextBlock element will be used to display the results of our call to the web service.

Step 4: Add a new project to the solution of type ASP.Net Web Application

This will be the Silverlight Host project.

image

  • Call it ‘SilverlightHost’.
  • Select this project as the Startup Project.
  • Delete the Default.aspx and related code behind files from the project.
Step 5: Add a Silverlight Application Reference to the Silverlight Host

This will link the host project to the Silverlight client project.

  • Right Click on the SilverlightHost project node and select ‘Add Silverlight Link…’
  • You will be prompted to select the SilverlightApp project in the current solution.
  • Click OK.

image

By linking the 2 projects, the SilverlightApp assemblies and XAML will be pulled into the SilverlightHost project on each build. There will be no need to pull files from multiple directories using this technique.

You will be prompted to enable Silverlight debugging for this project. Debugging is good so select ‘Yes’.

image

Step 6: Copy files from the SilverlightApp project to the SilverlightHost project

The project linking process described above makes sure that the XAML and client assembly are moved into the host project but in ‘Orcas’ Beta 1 it does not move the Silverlight.js or the HTML page that loads the Silverlight plug-in into the host project. You need to do this manually:

  • Copy Silverlight.js, TestPage.html and TestPage.html.js into the SilverlightHost project
  • Rename TestPage.html to Default.html
  • Set Default.html as the Startup Page

Note that even though we created an ASP.Net Web project as our host, we are not using any ASPX pages with associated code-behind. This is because this Web project is compiling to .Net Framework 3.5 and our deployment environment is based on .Net Framework 2.0. For debugging purposes we will need to keep our development environment based on .Net Framework 3.5. By avoiding server side code in the web host, we can deploy the SilverlightHost project to a .Net Framework 2.0 environment without making any modifications. [more on deployment later]

Step 7: Add a Web Service to the Silverlight Host project

Since there aren’t any dynamic web pages in our solution, all the server side code will be handled by web services. In order to avoid cross domain scripting issues in our development environment, the web services called from the SilverlightApp must reside within the SilverlightHost project. If you already have existing ASP.Net 2.0 ASMX web services you want to reuse, what you can do is add a web service to the SilverlightHost project that wraps the call to the legacy web service. In either case we will need to revisit the web services when we get into deployment mode [did I mention more on deployment later? ].

We must also mark the web service scriptable. To do this reference the System.Web.Extensions name space, add the appropriate using statement and apply the [ScriptService] and [ScriptMethod] attributes to the class and method.

  • Right Click and select Add then New item
  • Select Web Service
  • Call it WebService1
  • Add a Reference in the SilverlightHost project to the System.Web.Extensions namespace
  • Mark the Service Class with the [ScriptService] attribute
  • Mark the HelloWorld() method with the [ScriptMethod] attribute
  • Build the project

image

Step 8: Add a Web Reference in the SilverlightApp to the Web Service

This will generate the proxy for the web service.

  • Right Click on the SilverlightApp project in the solution explorer
  • Select Add Web Reference…
  • Click on Web services in this solution
  • Click on ‘WebService1’
  • Click the Add Reference button

image

Step 9: Add a call to the web service in the SilverlightApp project

In this step we will be adding the client-side C# code to the Silverlight application that will invoke the web service asynchronously. Open Page.xaml.cs and:

  • Add a private data member to the Page class of type SilverlightApp.localhost.WebService1
  • Add code to instantiate the web service proxy.
  • Add code to call the web service end point asynchronously
  • Add a method to the class called ‘HelloWorld_Success’ that takes an IAsyncResult as input and updates XAML Objects with values from the web service call

The resulting code should look like this:

image

Step 10: Build and Run the Solution

Build the solution. View the Default.html page in the SilverlightHost project. The resulting Silverlight application should look like this. Isn’t it beautiful? Silverlight Rocks!

image

OK maybe that was a bit over the top but our focus here was not the visuals but the project infrastructure. Now that the infrastructure is in place you are ready to go to town on creating an amazing cross browser/cross platform Rich Internet Applications that leverage web services.

Now let’s delve into the steps necessary to deploy this amazing application.

Deploying Silverlight 1.1 Applications to Windows Server 2003

Up to this point we have been in development mode using Visual studio ‘Orcas’ Beta 1 and .Net Framework 3.5. That is exactly what we want for the SilverlightApp but not for our web services. In order to deploy this application, we will need to take the following steps:

  1. The Web Service will need to be back ported to .Net Framework 2.0 and deployed to the server environment.
  2. The Web Service Reference in the SilverlightApp will need to be replaced with a reference to the deployed .Net Framework 2.0 Web Service.
  3. The Solution will need to be rebuilt and the SilverlightHost will need to be deployed
Step 1: Create and Deploy .Net Framework 2.0 Versions of your Web Services

This step may be very easy if your Web Services already exist in this form and you simply wrapped your services in order to get your Silverlight Application functioning. If not you will need to back port your Web Service code using Visual Studio 2005.

If you are creating your scriptable service for the first time, remember to reference the Syste.Web.Script.Services namespace and mark your service and method scriptable using the [ScriptService] and [ScriptMethod] attributes. You must also configure the web service application to support calling Web services from script. In the Web.config file for the web service application, you must register the ScriptHandlerFactory HTTP handler, which processes calls made from script to .asmx Web services.

<system.web>

    <httpHandlers>

        <remove verb="*" path="*.asmx"/>

            <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory,

               System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,

               PublicKeyToken=31bf3856ad364e35"/>

    </httpHandlers>

</system.web>

Once that is complete, you can use whatever technique you use to deploy your web service application to the production environment. I use a hosted environment that supports FTP so I leverage the ‘Copy Web Site’ feature within Visual Studio.

image

Note that your deployed web services must be served up from the same domain as your SilverlightApp since we do not have a cross domain scripting feature as of yet. If you are mashing up services from different domains you will need to do the mashup on the server side and offer up your mashup endpoint to your SilverlightApp from your domain.

Step 2: Update the Service References in the SilverlightApp

Up to this point, the SilverlightApp has been referencing the web service that was within the SilverlightHost project. Now that we are moving to a production environment, we will want the SilverlightApp to reference our deployed .Net Framework 2.0 web services.

If you are moving between development and production for testing purposes, then what you can do is define 2 Web References, one for the ‘local’ development environment web service and one for the ‘live’ production environment web service. Then by using conditional compilation you can easily move between the development environment reference and the production environment reference.

Note in the Solution Explorer there are 2 Web References in the Silverlight Client project:

image

One is called LiveService and the other is called LocalService. I then use #pragmas in code to perform conditional compilation. The #define can be in code or handled in the build script.

image
Step 3: Build and Deploy the SilverlightHost

Now we are in the home stretch. You should rebuild the entire solution and move the SilverlightHost project files into your production environment. Visual Studio ‘Orcas’ Beta 2 does not have the ‘Copy Web Site’ enabled at this time so I use a manual FTP process to move the files from my system to my host environment.

The files/folders you want to move are:

  • ClientBin
  • Default.html
  • Page.xaml
  • Silverlight.js
  • TestPage.html.js
  • Any application specific folders such as images, scripts, etc.

A Real World Example

If you want to check out a real world example of an application built and deployed using this architecture visit https://www.bobfamiliar.com (yet another shameless plug). This site leverages a Silverlight 1.1 front end that invokes 2 ASMX Web Services for retrieving CD and Track information.

image

The Web Services are located at:

https://www.bobfamiliar.com/soundsfamiliarservices/soundsfamiliarservice.asmx

The XAML was created using Expression Blend August Preview. The application also demonstrates the use of animation (move your mouse over the CD covers), formatted TextBlock (liner notes), looping video (Silverlight Logo), click event handling (hyperlink text) and WMA and MP3 media streaming (click the play button).

Summary

Adopting unsupported technology and products introduces a great deal of risk. The capabilities and stability of the technology must outweigh that risk. In addition understanding the impact on both the development and production environments must be known in order to make the case for the adoption of early release technology

Silverlight 1.1 works well in this scenario and offers you an opportunity to leverage your .Net skills for creating Rich Internet Applications. Since the user interface is being handled entirely by XAML it only makes sense to leverage web services to provide the data to our application.

By using Silverlight 1.1 Alpha and Visual Studio 2008 Beta 2 combined with a host environment that is still based in .Net Framework 2.0 we incur some additional steps in getting our application deployed. But once you understand the issues and know how to work around them, the door is wide open for early adoption of this breakthrough platform.

Technorati Tags: Silverlight, Visual Studio 2008, ArchitecturePOV, Web Services