Windows Azure ASP.NET MVC 2 Role with Silverlight
- by GeekAgilistMercenary
I was working through some scenarios recently with Azure and Silverlight. I immediately decided a quick walk through for setting up a Silverlight Application running in an ASP.NET MVC 2 Application would be a cool project. This walk through I have Visual Studio 2010, Silverlight 4, and the Azure SDK all installed. If you need to download any of those go get em? now. Launch Visual Studio 2010 and start a new project. Click on the section for cloud templates as shown below. After you name the project, the dialog for what type of Windows Azure Cloud Service Role will display. I selected ASP.NET MVC 2 Web Role, which adds the MvcWebRole1 Project to the Cloud Service Solution. Since I selected the ASP.NET MVC 2 Project type, it immediately prompts for a unit test project. Because I just want to get everything running first, I will probably be unit testing the Silverlight and just using the MVC Project as a host for the Silverlight for now, and because I would prefer to just add the unit test project later, I am going to select no here. Once you've created the ASP.NET MVC 2 project to host the Silverlight, then create another new project. Select the Silverlight section under the Installed Templates in the Add New Project dialog. Then select Silverlight Application. The next dialog that comes up will inquire about using the existing ASP.NET MVC Application I just created, which I do want it to use that so I leave it checked. The options section however I do not want to check RIA Web Services, do not want a test page added to the project, and I want Silverlight debugging enabled so I leave that checked. Once those options are appropriately set, just click on OK and the Silverlight Project will be added to the overall solution. The next steps now are to get the Silverlight object appropriately embedded in the web page. First open up the Site.Master file in the ASP.NET MVC 2 Project located under the Veiws/Shared/ location. After you open the file review the content of the <header></header> section. In that section add another <contentplaceholder></contentplaceholder> tag as shown in the code snippet below. <head runat="server">
<title>
<asp:ContentPlaceHolder ID="TitleContent" runat="server" />
</title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeaderContent" runat="server" />
</head>
I usually put it toward the bottom of the header section. It just seems the <title></title> should be on the top of the section and I like to keep it that way.
Now open up the Index.aspx page under the ASP.NET MVC 2 Project located in the Views/Home/ directory. When you open up that file add a <asp:Content><asp:Content> tag as shown in the next snippet.
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID=headerContent ContentPlaceHolderID=HeaderContent runat=server>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
</p>
</asp:Content>
In that center tag, I am now going to add what is needed to appropriately embed the Silverlight object into the page. The first thing I needed is a reference to the Silverlight.js file.
<script type="text/javascript" src="Silverlight.js"></script>
After that comes a bit of nitty gritty Javascript. I create another tag (and for those in the know, this is exactly like the generated code that is dumped into the *.html page generated with any Silverlight Project if you select to "add a test page that references the application". The complete Javascript is below.
function onSilverlightError(sender, args) {
var appSource = "";
if (sender != null && sender != 0) {
appSource = sender.getHost().Source;
}
var errorType = args.ErrorType;
var iErrorCode = args.ErrorCode;
if (errorType == "ImageError" || errorType == "MediaError") {
return;
}
var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";
errMsg += "Code: " + iErrorCode + " \n";
errMsg += "Category: " + errorType + " \n";
errMsg += "Message: " + args.ErrorMessage + " \n";
if (errorType == "ParserError") {
errMsg += "File: " + args.xamlFile + " \n";
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
}
else if (errorType == "RuntimeError") {
if (args.lineNumber != 0) {
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
}
errMsg += "MethodName: " + args.methodName + " \n";
}
throw new Error(errMsg);
}
I literally, since it seems to work fine, just use what is populated in the automatically generated page. After getting the appropriate Javascript into place I put the actual Silverlight Object Embed code into the HTML itself. Just so I know the positioning and for final verification when running the application I insert the embed code just below the Index.aspx page message. As shown below.
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>
<%= Html.Encode(ViewData["Message"]) %></h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">
http://asp.net/mvc</a>.
</p>
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
width="100%" height="100%">
<param name="source" value="ClientBin/CloudySilverlight.xap" />
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="4.0.50401.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.0" style="text-decoration: none">
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight"
style="border-style: none" />
</a>
</object>
<iframe id="_sl_historyFrame" style="visibility: hidden; height: 0px; width: 0px;
border: 0px"></iframe>
</div>
</asp:Content>
I then open up the Silverlight Project MainPage.xaml. Just to make it visibly obvious that the Silverlight Application is running in the page, I added a button as shown below.
<UserControl x:Class="CloudySilverlight.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="48,40,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</UserControl>
Just for kicks, I added a message box that would popup, just to show executing functionality also.
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("It runs in the cloud!");
}
I then executed the ASP.NET MVC 2 and could see the Silverlight Application in page. With a quick click of the button, I got a message box. Success!
Now the next step is getting the ASP.NET MVC 2 Project and Silverlight published to the cloud. As of Visual Studio 2010, Silverlight 4, and the latest Azure SDK, this is actually a ridiculously easy process.
Navigate to the Azure Cloud Services web site.
Once that is open go back in Visual Studio and right click on the cloud project and select publish.
This will publish two files into a directory. Copy that directory so you can easily paste it into the Azure Cloud Services web site. You'll have to click on the application role in the cloud (I will have another blog entry soon about where, how, and best practices in the cloud).
In the text boxes shown, select the application package file and the configuration file and place them in the appropriate text boxes. This is the part were it comes in handy to have copied the directory path of the file location. That way when you click on browser you can just paste that in, then hit enter. The two files will be listed and you can select the appropriate file.
Once that is done, name the service deployment. Then click on publish. After a minute or so you will see the following screen.
Now click on run. Once the MvcWebRole1 goes green (the little light symbol to the left of the status) click on the Web Site URL. Be patient during this process too, it could take a minute or two. The Silverlight application should again come up just like you ran it on your local machine.
Once staging is up and running, click on the circular icon with two arrows to move staging to production. Once you are done make sure the green light is again go for the production deploy, then click on the Web Site URL to verify the site is working. At this point I had a successful development, staging, and production deployment.
Thanks for reading, hope this was helpful. I have more Windows Azure and other cloud related material coming, so stay tuned.
Original Entry