We have already briefly discussed the ASP.NET 3.5 Extensions
in Chapter 3. This package contains features
and controls that are planned for future releases of ASP.NET and .NET. Some
of these improvements have also been added to the Silverlight 2 Visual
Studio project. The automatically generated test pages we have been using
throughout this book are already using some of the new features, the
<asp:Silverlight>
control, now part
of Silverlight.
The <asp:Silverlight>
control lets you embed
XAML content into an ASP.NET page. We will have a look at what the
client-side HTML output looks like in a second; but before that, here are
the most important attributes of <asp:Silverlight>
:
Source
The URL of the Silverlight XAML file or .xap application to include.
Version
The minimum version of Silverlight that needs to be checked. If you are
displaying Silverlight 2 content, set this property to 2.0
.
ScaleMode
How to scale the embedded media. Possible values are
ScaleMode.None
(no scaling),
ScaleMode.Stretch
(stretch without keeping the aspect
ratio), and ScaleMode.Zoom
(stretch
and keep the aspect ratio).
Width
Height
Here is an example:
<asp:Silverlight ID="Silverlight1" runat="server" Source="MyApplication.xap" Version="2.0" Width="250" Height="250" />
To use this control, you may have to load the appropriate assembly, depending on which version of the Silverlight Tools for Visual Studio you use:
<%@ Register Assembly="System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %>
If you want to load JavaScript libraries to be used as part of the
Silverlight application, you can just put them into your Silverlight
project and they will be embedded into the .xap file as a resource. Alternatively, you can use the ASP.NET Ajax
ScriptManager
to
include the script file, by using the
<Script>
subelement:
<asp:ScriptManager ID="ScriptManager1" runat="server"> <Scripts> <asp:ScriptReference Path="myLibrary.js" /> </Scripts> </asp:ScriptManager>
The ScriptManager
is the web control that comes with
ASP.NET 3.5 and ASP.NET Ajax. It is responsible for setting up a web page
to use Ajax effects. To use <asp:Silverlight>
, you do need the ScriptManager
on the page:
<asp:ScriptManager id="ScriptManager1" runat="server" />
Example 12-1 contains the complete code.
Example 12-1. The Silverlight control (Xaml.aspx)
<%@ Page Language="VB" %> <%@ Register Assembly="System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Silverlight</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> <Scripts> <asp:ScriptReference Path="myLibrary.js" /> </Scripts> </asp:ScriptManager> <div> <asp:Silverlight ID="Silverlight1" runat="server" Source="MyApplication.xap" Version="2.0" Width="250" Height="250" /> </div> </form> </body> </html>
Let’s take a look at the output of this code that reaches the client browser:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1"><title> Silverlight </title></head> <body> <form name="form1" method="post" action="Xaml.aspx" id="form1"> <div> <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" /> <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" /> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value= "/wEPDwULLTIwNjM5Mzk4OTRkZNF37DotH05PENvf1Y3W3YmC8V7i" /> </div> <script type="text/javascript"> //<![CDATA[ var theForm = document.forms['form1']; if (!theForm) { theForm = document.form1; } function __doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument; theForm.submit(); } } //]]> </script> <script src="/Silverlight_Web/WebResource.axd?d=h7jv6SCZmgTnsK2N8O9afg2& t=633330467854218750" type="text/javascript"></script> <script src="/Silverlight_Web/ScriptResource.axd?d=RZvlBE1XEHoFrXN5cW_ 8HtIOXyYdtyaZxJnfjlxlZL640qPYEo1Kc1_2vchcada_ ycHahSChhx1W0B4qCsolJPqmNPeWZyiLjPGy9WzbkJQ1&t=1c483a7e" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ if (typeof(Sys) === 'undefined') throw new Error('ASP.NET AJAX client-side framework failed to load.'), //]]> </script> <script src="/Silverlight_Web/ScriptResource.axd?d=RZvlBE1XEHoFrXN5cW_ 8HtIOXyYdtyaZxJnfjlxlZL640qPYEo1Kc1_2vchcada_EdhoiP9GUYgHnuZNHQXq0OSUq_ SVfB3BjV4tsn4D1gMymQD8Y_Zkz_Wp6ogxiaxz0&t=1c483a7e" type="text/javascript"></script> <script src="myLibrary.js" type="text/javascript"></script> <script src="/Silverlight_Web/ScriptResource.axd?d=RZvlBE1XEHoFrXN5cW_ 8HtIOXyYdtyaZxJnfjlxlZL640qPYEo1Kc1_2vchcada_vKNOVG561JTyxFIC7zJJOzBzeq7- ofGFoIv4NnyzjxI1&t=1c483a7e" type="text/javascript"></script> <script src="/Silverlight_Web/ScriptResource.axd?d=RZvlBE1XEHoFrXN5cW_ 8HtIOXyYdtyaZxJnfjlxlZL640qPYEo1Kc1_2vchcada_4xwJThWwnvKjzBML27niE638t RTbr6XMXg9jG3o9l0g1&t=1c483a7e" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ Sys.WebForms.PageRequestManager._initialize('ScriptManager1', document.getElementById('form1')); Sys.WebForms.PageRequestManager.getInstance()._updateControls([], [], [], 90); //]]> </script> <div> <span id="Silverlight1_parent"></span> <script type="text/javascript"> //<![CDATA[ Sys.UI.Silverlight.Plugin.create("Silverlight1_parent", "2.0", 1, "u003cobject type="application/x-silverlight-2-b2" data="data:," id="Silverlight1" style="height:250px;width:250px;"u003e u003c/objectu003e"); //]]> </script> </div> <script type="text/javascript"> //<![CDATA[ Sys.Application.initialize(); Sys.Application.add_init(function() { $create(Sys.UI.Silverlight.Control, {"source":"MyApplication.xap"}, null, null, $get("Silverlight1")); }); //]]> </script> </form> </body> </html>
This is quite a lot of code—compare it to the markup we have in the
Xaml.aspx file!—so we will break it
down into individual parts. The hidden form fields are added by ASP.NET,
so there is nothing new or surprising here. This also includes the
first <script>
element.
However, the next four <script>
elements are
automatically added by Silverlight. One accesses WebResource.axd, and the next three access
ScriptResource.axd. These <script>
elements load JavaScript
resources that are embedded in the ASP.NET Extensions assemblies. This includes the
ASP.NET Ajax client script libraries, as well as special JavaScript code
used to check for the Silverlight plug-in and to initialize the
Silverlight content on the page, similar to the code first introduced in
Chapter 3.
The next <script>
element loads myLibrary.js, the file we provided in the <Scripts>
section of <asp:ScriptManager>
, using <asp:ScriptReference>
. The
remaining <script>
sections on the page initialize both
ASP.NET Ajax and the XAML control on the page. The XAML control is
embedded using the <object>
HTML tag:
<object id="Xaml1" type="application/x-silverlight-2-b2"></object>
So, what we are basically getting here is output similar to the
output created by the Silverlight project template. The XAML file is put
into an <object>
tag (note the type application/x-silverlight-2-b2
; Silverlight 1.0
is still supported by using application
/x-silverlight)
, and a JavaScript library takes
care of initializing the XAML content and checking for the correct
plug-in. The markup created by <asp:Silverlight>
is a bit longer than
our “handcoded” markup, but it is also a bit faster to create in the IDE
because we no longer have to write any JavaScript code ourselves.
Make absolutely sure that you set the Width
and
Height
properties, as not all browsers figure that out
automatically. Figure 12-1 shows what happens if you omit
these two attributes. Internet Explorer shows the content (at least most
of it), but Firefox does not.
If you only want
to use media on your Silverlight page (i.e., movie and audio data), you
can even avoid creating the necessary XAML yourself. The Silverlight SDK
contains a special web control called <asp:MediaPlayer>
that takes care of both setting up the required XAML and embedding it into
the web page (like <asp:Silverlight>
does). The web
control supports several properties, and the following is a list of the
most interesting ones, apart from the mandatory Width
and
Height
:
MediaSource
AutoPlay
Whether the media will be played automatically once the page has been
loaded (true
) or not (false
)
Muted
Whether the audio will be off (probably not a bad idea for commercial web sites)
PlaceholderImageUrl
The URL of an image that is displayed as a placeholder while the media content is loaded
ScaleMode
How to scale the content; choose from ScaleMode.None
(no
scaling), ScaleMode.Stretch
(stretch without keeping the aspect ratio), and ScaleMode.Zoom
(stretch and keep the
aspect ratio)
Volume
As with <asp:Silverlight>
,
<asp:MediaPlayer>
also requires a
ScriptManager
control to be present. Example 12-2 shows a page with an embedded WMV video. No XAML or
JavaScript is to be seen.
Example 12-2. Embedding media content (Media.aspx)
<%@ Page Language="C#" %> <%@ Register Assembly="System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Silverlight</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <asp:MediaPlayer ID="Media1" runat="server" MediaSource="video.wmv" AutoPlay="true" Width="320" Height="240" /> </div> </form> </body> </html>
The client output of the preceding code is very similar to the one
<asp:Silverlight>
was creating in the previous section.
However, there are two obvious changes: the <object>
tag is missing (but is created by
JavaScript code), and the initialization method sets up the MediaPlayer
control:
<div> <span id="Media1_parent"></span> <script type="text/javascript"> //<![CDATA[ Sys.UI.Silverlight.Plugin.create("Media1_parent", "1.0", 1, "u003cobject type="application/x-silverlight" data="data:," id="Media1" style="height:240px;width:320px;"u003e u003c/objectu003e"); //]]> </script> </div> <script type="text/javascript"> //<![CDATA[ Sys.Application.initialize(); Sys.Application.add_init(function() { $create(Sys.UI.Silverlight.MediaPlayer, {"autoPlay":true,"mediaSource": "video.wmv","scaleMode":1,"source":"/Silverlight_Web/WebResource.axd?d=UWvRBn2D vlAG1qPj1sEy8HZXD30sZ0KcGEYDUyVCC-Hn51Pnb5xTrEvCUJJOmiUwlEsRMyw82Qw4YzS6q3RmGBy 9jFQYPNgFIpKmO8HkyTk1&t=633378050096020000"}, null, null, $get("Media1")); }); //]]> </script>
Indeed, the JavaScript code embeds the media using the
<object>
HTML element. This is no surprise, since
<asp:MediaPlayer>
is creating XAML markup to embed the
video or audio content. However, the initialization of this
<object>
element, in the <script>
section, is different. The source
property is set to this URL
(the exact name will vary on your system, because the current time is
embedded in the URL):
/Silverlight_Web/WebResource.axd?d=UWvRBn2DvlAG1qPj1sEy8HZXD30sZ0KcGEYDUyVCC-Hn 51Pnb5xTrEvCUJJOmiUwlEsRMyw82Qw4YzS6q3RmGBy9jFQYPNgFIpKmO8HkyTk1&t=633378050096 020000
So, no static XAML file is sent down to the browser; instead, the ASP.NET Futures creates a handler that will return dynamically generated XAML content. In case you are curious, use a tool such as Firebug (http://www.getfirebug.com/) to sniff incoming traffic and have a look at the dynamic XAML. Figure 12-2 shows the result; as you can see, that’s quite a lot of markup, since the output not only shows the media file, but also includes a visual user interface for it. How lucky we are that we did not have to create that ourselves.
The Media
control also supports subelements. One is
<Scripts>
, which allows you to load the JavaScript
libraries you need in a movie. Another one is
<Chapters>
. This allows you to use markup to add
chapters to a movie (see Chapter 8 to learn how to do that
manually). For each chapter marker, you need an
<asp:MediaChapter>
element and the following
properties:
Example 12-3 shows what this can look like, and Figure 12-3 shows the output in the web browser; when you hover over the video, all markers are shown. Clicking on one of them jumps to the appropriate position in the video.
Example 12-3. Adding chapters to a video (MediaChapter.aspx)
<%@ Page Language="C#" %> <%@ Register Assembly="System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title>Silverlight</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <asp:MediaPlayer ID="Media1" runat="server" MediaSource="video.wmv" AutoPlay="true" Width="320" Height="240"> <Chapters> <asp:MediaChapter Position="13.200" Title="Junction" ThumbnailImageSource="marker1.png" /> <asp:MediaChapter Position="26.300" Title="Olympic Stadium" ThumbnailImageSource="marker2.png" /> <asp:MediaChapter Position="48.0" Title="Olympic Tower" ThumbnailImageSource="marker3.png" /> </Chapters> </asp:MediaPlayer> </div> </form> </body> </html>
All you need to know about ASP.NET Ajax and its related projects, including the ASP.NET Ajax Futures (the predecessor of the ASP.NET 3.5 Extensions)