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.
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:
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 (http://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:
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
<ShamelessPlug> I use Discount ASP (http://www.discountasp.com) for my hosting needs. They are awesome and I highly recommend them. </ShamelessPlug>
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.
File, New, Project, Other Project Types
This will be the Silverlight Client project.
File, Add, New Project
This will be the placeholder for the data returned by our web service.
Give the TextBlock the name ‘TheMessage’. The TextBlock element will be used to display the results of our call to the web service.
This will be the Silverlight Host project.
This will link the host project to the Silverlight client project.
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’.
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:
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]
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.
This will generate the proxy for the web service.
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:
The resulting code should look like this:
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!
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.
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:
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>
<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.
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.
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:
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.
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:
If you want to check out a real world example of an application built and deployed using this architecture visit http://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.
The Web Services are located at:
http://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).
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.
Liquid Boy blog has a great set of posts on building a Silverlight v1.1 application that looks like the
Great post, helped me figure out why my deployed enviroment wasnt working. Of course the silverlight app must be compiled against the deployed relay service in the host - doh!
Great article. Ill make sure to mention on my BLOG as well.
Glad it was useful Jacob! -bob
Thanks, Bob. This saved me hours of work!
In the Silverlight forums there are guides to developing Silverlight 1.1 apps using VS 2005 that can allow for more fine grained control of your projects. But with the drawback of no 'Orcas' specific features can be used.
That is a great caveat you suggested: capabilities should outweigh risk. For example, the functions found in the System.Windows.Browser namespace in System.Silverlight.dll allow complete client side access to the entire hosting DOM tree. It can lead to very powerful RIA scenarios but is quite experimental, both technically and usability-wise.
You've been kicked (a good thing) - Trackback from DotNetKicks.com
Silverlight Cream for September 24, 2007
"what you can do is add a web service to the SilverlightHost project that wraps the call to the legacy web service"
Doesn't this double the number of TCP connections on the server-side?
The suggestions here are work arounds for limitations that exist with the alpha release. I suspect that as Silverlight 1.1 moves into Beta, I will need to revisit this article and update it based on new features. -bob
In my last post I announced the ReMIX07 Boston Soundtrack application and provided the iframe for embedding
THANK YOU! This post made my life much easier. :)
I have spent a lot of time recently coming up to speed with Silverlight 1.1. It is the alpha version
I have spent a lot of time recently coming up to speed with Silverlight 2.0. It is the alpha version