Silverlight and the Rich Client Browser

The hosting model of Microsoft Silverlight


February 11, 2008
URL:http://www.drdobbs.com/windows/silverlight-and-the-rich-client-browser/206401671

Dino writes the ASP.NET-2-The-Max column for Dr. Dobb's. He can be contacted at weblogs.asp.net/despos/.


As dramatic as it may sound, the Web was not invented sort of 20 years ago to deliver rich pages and applications--at least, in the today's acceptation of terms like rich pages. The Web was designed and implemented to share documents and to link one document to a related one published to the same network. HTML and HTTP, respectively the markup language and transportation protocol, were tailor-made to serve plain text with a bit of formatting, sparse images and a few hyperlinks.

The Web became officially a public resource in 1993; 15 years later, we're still using HTML and HTTP to create true applications with a rich presentation layer and sophisticated back ends. And then we complain about bandwidth, slow rendering, and an overall cumbersome model of interaction between the user and the system. The growing demand for rich Internet-based applications has brought to the conclusion that only a new generation of applications can let Web architects keep up with it. The AJAX paradigm is definitely a quantum leap for Web architects. AJAX solves many problems, but it also raises new problems and sharpens existing, but partially latent, issues. But AJAX is a paradigm for enriching traditional Web applications-based on HTML and powered by script languages. But unfortunately, HTML and JavaScript are not necessarily the ideal tools to rely on when you want rich graphics, animation, media capabilities, and programming power.

Well 10 years ago Microsoft made a first attempt to give developers a rich programming environment for the Web. It was in late 1990s when the ActiveX technology came along. All in all, ActiveX was a bit ahead of time and, more importantly, had serious flaws in key areas for Web applications, such as interoperability and security. Similar in the overall idea of being a browser plug-in, but cross-platform and with a better security model, Adobe Flash imposed itself as the de facto standard for rich interface over the Web. In September 2007, Microsoft released version 1.0 of an analogous product-Silverlight-which is clearly a competitor to Flash but with some good arrows in the quiver.

Today, both Flash and Silverlight are evolving into something different that goes beyond the role of the player for some graphically rich content. Flex and Silverlight 2.0 are expected to deliver more programming power to be consumed within the boundaries of the browser, but rigorously on the client. It's like having a new type of client for the front-end of our enterprise applications-the rich client browser.

Enter Silverlight

Formerly code-named WPF/Everywhere, Silverlight is a free browser plug-in that is currently available for the Windows and Mac platform under a variety of operating systems including Windows Server 2003, Windows Vista, Windows XP SP2, Macintosh OS X 10.4.8 and newer versions for both Power PC-based and Intel-based hardware. Silverlight supports all major browsers available on these platforms such as Firefox, Netscape, Safari, Internet Explorer.

As you can see, there's currently no support for Linux, mobile systems, and some older versions of Windows. However, this is not necessarily a situation destined to last for too long. Silverlight support for Linux systems is coming through the efforts of the Mono group. You can read more on the progress by visiting http://www.mono-project.com/moonlight. Support for mobile systems is being experimented at this time. Microsoft also has announced to have plans to support Silverlight on Windows 2000. You have no hopes, however, to ever install Silverlight successfully on, say, Windows 98.

The mission of Silverlight is clearly explained by its former code-name: WPF/Everywhere. That's what Silverlight really does: it brings the power of Windows Presentation Foundation-the presentation subsystem of the .NET Framework 3.x-to the Web. The idea is hosting the Silverlight engine into the browser to let it process WPF content aptly downloaded from a remote URL.

Silverlight is not intended to replace the browser, but is designed to be hosted in the browser as a plug-in. For this reason, designing some Silverlight content is a two-step operation. First, you create the WPF content you want to deliver through the Web. Second, you prepare a host Web page where you reference and configure the Silverlight plug-in. Users just navigate to a Web page and if the page requires Silverlight they are automatically prompted to install it and proceed with the features designed for the page. This model is nothing new and is fairly familiar to most Web users; see Figure 1.

[Click image to view at full size]
Figure 1: Users are prompted to install the Silverlight plug-in when required

Let's dig out the nitty-gritty details of how the Silverlight engine is referenced and configured by page developers. Before going any further, though, I feel I need to add something on the versions of Silverlight currently available. As mentioned, Microsoft released version 1.0 in September 2007; at the same time, Microsoft also leaked to the Web the alpha of version 1.1. Late in 2007, the version number of the alpha was changed to 2.0 and a beta for version 2.0 has been released as of Spring 2008. Version 2.0 represents a huge step forward in terms of functionality. However, the hosting model, that is the way in which you reference and activate the engine from within Web pages, will not undergo significant changes.

Serving Up Silverlight-Enabled Web Pages

A Silverlight-enabled page is a regular Web page that you can create using any development platform, whether a classic ASP or HTML page, an ASP.NET page, an ASP.NET AJAX page, or even a PHP page. The host Web page must meet a couple of key requirements. First off, it must reference a particular JavaScript file that contains the object model to drive the Silverlight engine. Second, the host page must include some boilerplate JavaScript code to initialize the engine if installed, or to display the install prompt otherwise as in Figure 1.

The Silverlight object model is contained in a file named silverlight.js that you get out of the box when you install on the server machine the Silverlight SDK. In the host page, you reference this file from your server using a classic <script> tag.

<script type="text/javascript" src="silverlight.js"></script>

The file contains a JavaScript object named Silverlight. This object exposes essentially methods to test whether the plug-in is installed and to generate the markup that will incorporate the plug-in in the page as an <object> tag (see Figure 2). A Web page can contain multiple instances of the Silverlight plug-in each bound to a different WPF content.

[Click image to view at full size]
Figure 2: The DOM of a HTML page that contains a Silverlight plug-in.

The Silverlight plug-in may appear everywhere in the host page. You decide size and location of the plug-in by using the following combination of HTML markup and JavaScript code.

<div id="Host"> <script type="text/javascript"> createSilverlightHost();

</script> </div>

In this case, the Silverlight plug-in will appear within the surrounding <div> tag. If you want it to flow with the remainder of the page, you replace the <div> element with a <span> element. The JavaScript function createSilverlightHost is piece of boilerplate code that you add to, or reference from, each Silverlight-enabled page.

Listing One shows the typical body of the function.

function createSilverlightHost()
{  
 Silverlight.createObject(
     "page.xaml",                   
     document.getElementById("Host"),                   
     "SilverlightControl1",          
     {                                
         width:'300',                
         height:'200',               
         version:'1.0'               
     },
     {
         onError:null,      
         onLoad:null        
     },
     null);                 
}
Listing One: Creating and configuring the Silverlight plug-in in a Web page

The Silverlight.createObject method is ultimately responsible for instantiating the Silverlight plug-in when the browser gets to render the portion of page where the plug-in is destined to live. You pass the method the URL to the WPF content to download and render as well as the parent DOM element and the ID to use to reference the plug-in programmatically. It should be noted that the Silverlight initialization script can be placed anywhere in the page. In other words, the parent element of the plug-in in the page is not inferred from the position of the initialization <script> tag, but is rather explicitly specified as a parameter to the Silverlight.createObject method.

function createSilverlightHost() {  
    Silverlight.createObject(contentURL,                   
        document.getElementById("Host"),                   
        "SilverlightControl1",  ... );
}

The net effect of the Silverlight.createObject method is the dynamic creation an <object> tag that is added a child to the specified parent element. The third argument to the method is just the unique ID for the newly created <object> element. You can later use this ID to reference the plug-in programmatically. The Silverlight.createObject method accepts the arguments listed in Table 1.

Parameter

Description

source

Indicates the XAML file providing the content.

parentElement

Indicates the DOM element which will host the Silverlight plug-in.

ID

Indicates the unique ID of the Silverlight instance being created.

properties

Indicates an array of properties to be set on the engine. You set properties using a string-based notation {prop1:value, . , propN:value}. All values are of type String.

events

Indicates an array of events to be handled from within the engine. You set event handlers using a string-based notation {event1:handler, ., eventN:handler}.

userContext

Indicates an optional object that will be passed as a parameter to the load event handler function for the current instance of Silverlight.

 

Table 1: Arguments of the Silverlight.createObject function

The properties to configure the plug-in are listed in Table 2.

Property

Default Value

Description

background

white

Indicates the background color of the region that displays the Silverlight content.

enableHtmlAccess

true

Indicates whether the content hosted in the Silverlight control has access to the browser's DOM.

frameRate

24

Indicates the maximum number of frames to render per second.

height

0

Indicates the height of the rectangular region that displays the Silverlight content.

inplaceInstallPrompt

false

Indicates whether in-place install prompt should appear if the specified version of the Silverlight control is not installed on the browser. When set to false, the standard prompt appears linking users to the Silverlight's download page. When set to true, a different prompt appears to let users install Silverlight in place.

isWindowless

false

Indicates whether the control displays in a window-less manner.

version

""

Indicates the Silverlight version required to run the application.

width

0

Indicates the width of the rectangular region that displays the Silverlight content.

 

Table 2: Properties supported by the Silverlight engine.

Most of these properties are optional; in a realistic page you typically assign an explicit value to width, height, and version. These properties are used to initialize the Silverlight plug-in, but only a few of them are programmatically exposed through the Silverlight object and can be retrieved at run time from JavaScript code. These properties are isWindowless, background, and enableHtmlAccess. The corresponding runtime properties take the following names: Windowless, Background, and EnableHtmlAccess. You access these properties using the settings property on the plug-in object, as in the following code snippet:

var plugin = document.getElementById("SilverlightControl1");
plugin.settings.Background = "yellow";

The Silverlight plug-in also features a limited event model based on two events -- load and error. The load event occurs after the WPF content in the Silverlight plug-in has completely loaded. The error event is fired if any error occurs during the processing of the WPF content. You can define JavaScript handlers for these events using the events properties of the Silverlight.createObject method (see Listing One).

The Silverlight plug-in can either be hosted in a portion of the container page or cover the entire page. If you want the plug-in to expand up to cover the full browser area, then you set width and height properties to 100 percent.

Content for a Silverlight Plug-In

A Silverlight-enabled page is centered on a XAML file. XAML is a declarative XML-based language used in Windows Presentation Foundation (WPF) to define user-interface elements, data binding, events, and other features. The URL that the Silverlight plug-in points to must return XAML data. It can either be a static XAML file deployed to the Web server or a dynamic resource that returns a response of type text/xaml. For example, it could be an ASP.NET HTTP handler.

Depending on the version of Silverlight you support, you can have a XAML document with a different set of tags. Silverlight 1.0 supports a small subset of the whole XAML syntax limited to a few elements such as media, rectangle, canvas, textblock and a few more. Silverlight 2.0, which will be released in the course of 2008, is expected to support the full range of XAML elements thus making possible 100-percent WPF programming over the Web.

You can build the XAML source file using two primary development tools -- Expression Blend and/or Visual Studio 2008. Mostly targeted to designers, Expression Blend lets you create interactive UIs and media-rich experiences. With Visual Studio 2008, instead, developers can author XAML script by typing and make it even richer by adding both script and managed code. (Managed code, though, is only supported in Silverlight 2.0.)

The XAML content is downloaded to the client and cached as any other Web resource. Next, the plug-in parses the content and converts it into an object model. Finally, the content is rendered into the browser. The browser has no direct exposure to XAML. The browser simply points to a URL that serves a HTML page. The script in the page creates the <object> tag to reference the Silverlight plug-in. Finally, the plug-in takes care of downloading XAML and processing it. In Silverlight 2.0, the plug-in will also download client assemblies to back up the XAML.

The source XAML can also be embedded in the host page as inline text. You use a special <script> tag with a type of text/xaml. From the browser's perspective, this content is nothing more than a data island and, as such, it is blissfully ignored when it comes to render the page.

<script type="text/xaml" id="xamlContent">
    <?xml version="1.0"?>
    <Canvas xmlns="http://schemas.microsoft.com/client/2007">
       :
    </Canvas>
</script>

How can you bind this chunk of XAML markup to the Silverlight plug-in? You give the <script> tag that contains the inline XAML a unique ID and use that ID prefixed by # as the URL of the document:

Silverlight.createObject("#xamlContent",  ...);

It is key to note that the <script> tag with the inline XAML content must precede the HTML element that contains the Silverlight plug-in.

If any errors occur during the processing of the XAML content, the error event is fired. If the exception goes unhandled, then a system defined function kicks in and displays a client message box such as that in Figure 3.

Figure 3: The Silverlight's default error handler

If you want to write a custom error handler, then you create a JavaScript as below and bind it to the onError property you see in Listing One.

function onErrorOccurred(sender, args)
{
    var msg = "Silverlight Error: \n\n";

    msg += "Error Type:    " + args.errorType + "\n";
    msg += "Error Message: " + args.errorMessage + "\n";
    msg += "Error Code:    " + args.errorCode + "\n";
    alert(msg);
}

The sender argument represents the object that the error occurred on. The args argument returns information about the error type, message, and code. If it were a parser error, then you find also information about the XAML element and position in the file. If it were a runtime error, then the argument also indicates the method where the error occurred.

Silverlight Pages and Applications

The Silverlight plug-in can be the only element contained in the host page or the page can contain other ASP.NET controls and HTML literals. If the Silverlight plug-in is the only element in the Web page, you're likely having a full-screen WPF application operating over the Web. It's still a sandboxed application, but with rich graphic and media capabilities. In Silverlight 1.0, you use JavaScript to add glue code and logic to make the various XAML elements interact. In Silverlight 2.0, in addition to JavaScript (it will actually be Managed JScript) you can also use any other supported .NET managed language such as C# and Visual Basic .NET.

The Silverlight plug-in, however, can also take a small portion of the Web page and be mixed up with classic HTML elements. In this case, you can arrange Silverlight-to-HTML communication and use JavaScript to dynamically edit the contents of the XAML document. If HTML access is enabled, you first retrieve the DOM element that represents the Silverlight plug-in and then use the Silverlight object model to access the content. Here's an example:

var plugin = document.getElementById("SilverlightControl1");
var textBlock = plugin.content.findName("status");
textBlock.text = "...";

The property content points to the root of the XAML document. The method findName lets you locate any XAML element with a x:Name property set to the specified string. Once you hold a reference to a XAML element, you proceed with the element specific object model to make changes. Finally, you should note that some XAML property may actually be attached properties and not just direct properties defined on the object. An attached property, for example, is the Left property that, defined on the Canvas element, is actually assigned by any XAML element child of the Canvas. Here's the syntax you use to programmatically read or write an attached property:

textBlock["Canvas.Left"] = 100;

You can also access properties via a pair of get/set methods, as below:

textBlock.setValue("Canvas.Left", 100);

In this case, the setValue method hides the difference between direct and attached properties.

Conclusion

Silverlight is the Web extension to WPF and this statement will be even truer with the advent of Silverlight 2.0 and the announced full support for managed languages on the client. Basically, it will be a revamped ActiveX platform, just done properly from the interoperability and security standpoint. Silverlight is a browser plug-in that constitute a separate download for all users. Users can choose to install Silverlight as they navigate to a page that requires it or in an offline manner. Unlike AJAX, Silverlight is an extension to the Web that is realized via a plug-in-the only possible way to add new features to existing browsers. For this reason, you still need a Web page to point users to and wrapping the plug-in. This article discussed the hosting model and possible ways for pages to interact with Silverlight-hosted documents.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.