ASP.NET MVC and Silverlight Playing Nice: Part Two

Now that I have been using my Silverlight helpers for sometime on my work and fun projects, I thought I would revisit my ASP.NET MVC and Silverlight playing nice post. I have added just a few features to it and I wanted to give you more code so that others can use this simple way to add Silverlight to ASP.NET MVC. I do not want to repeat myself too much so I'll just show you some code. Most of it has been explained in the last post but some will be new.

The first step is to create your Silverlight partial view. I find it better to write the view before the model for stuff like this. If you write the model first you will write the view to fit the model rather than writing the model to fit the view. This view will replace the test page you get from adding a Silverlight application to your MVC application. Here is my new partial.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

<form id="form1" runat="server" style="height:100%">
  <div id="silverlightControlHost">
    <object data="data:application/x-silverlight-2,"
            type="application/x-silverlight-2"
            width="<%: Model.Size.Width %>"
            height="<%: Model.Size.Height %>">
      <param name="source"
             value="<%: Url.Content("~/ClientBin/" + Model.XapName + ".xap") %>"/>
      <param name="onError"
             value="<%: Model.OnSilverlightError %>" />
      <param name="background"
             value="<%: Model.BackgroundColor.Name %>" />
      <param name="minRuntimeVersion"
             value="<%: Model.MinimumRuntimeVersion %>" />
      <param name="autoUpgrade"
             value="<%: Model.AutoUpgrade %>" />
      <% if (Model.Parameters != null && Model.Parameters.Count > 0) { %>
          <param name="initParams" value="<%: Model.ParameterString %>" />
      <% } %>
      <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="slhistoryFrame" style="visibility:hidden;height:0px;width:0px;border:0px">
    </iframe>
  </div>
</form>

If you read the last post you will see that I changed my partial a bit.

I added the colon to the code nuggets to get the implied Html.Encode calls. I also added parameters. I found that my Silverlight applications needed to know some info about my MVC applications to work. In one example I have, my file upload Silverlight control needed to know where to store the meta data in my database about the file being uploaded. To do this, I conditionally add the parameter element then add the parameters I want using a name value pair dictionary. Remember that this is going to be a display template so you need to put it in Views > Shared > DisplayTemplates folder and name it with the same name of the type you are strongly typing it to. In this case it will be SilverlightObject.

Next you will want to create a model that will hold the info on how to load your Silverlight control. You'll see that it is pretty simple. Here is mine.

public class SilverlightObject
{
    public string XapName { get; set; }
    public Size Size { get; set; }
    public string OnSilverlightError { get; set; }
    public Color BackgroundColor { get; set; }
    public string MinimumRuntimeVersion { get; set; }
    public bool AutoUpgrade { get; set; }
    public IDictionary<string, string> Parameters { get; set; }

    public string ParameterString
    {
        get
        {
            StringBuilder sb = new StringBuilder();

            foreach (var parameter in Parameters)
            {
                sb.Append(parameter.Key);
                sb.Append("=");
                sb.Append(parameter.Value);

                if (Parameters.Count > 1)
                    sb.Append(",");
            }
            return sb.ToString();
        }
    }

    public SilverlightObject()
    {
        OnSilverlightError = "onSilverlightError";
        BackgroundColor = Color.Black;
        MinimumRuntimeVersion = "4.0.50524.0";
        AutoUpgrade = true;
    }
}

It is just a container for some very specific options for Silverlight that you plug into your partial view

Also, there is a property to get a parameter string so that we can simply drop that value into the parameter value if we have any. This is just another way to make the view extremely simple and not require business logic.This class is just saved in the models folder.

You will also want a ViewModel for whatever page you will be showing the Silverlight control on.Typically you would have a bit more in the view model an just the Silverlight control but for my example I will just have the Silverlight control.

public class IndexViewModel
{ public SilverlightObject SilverightSample; }

Now you just need to wire it up in true MVC fashion!

In my index Action of my home controller I will create a new SilverlightObject and pass it into my ViewModel which will be passed into my Index View.

public ActionResult Index()
{
    var parameters = new Dictionary<string, string>
    {
        { "MyParameter", "123" },
        { "Value", "123abc" }
    };

    var silverlight = new SilverlightObject
    {
        XapName = "SilverlightSample",
        Size = new Size(300, 300),
        Parameters = parameters
    };

    var model = new IndexViewModel
    {
        SilverightSample = silverlight
    };

    return View(model);
}

Now you can drop the control in your view that is strongly typed to your view model.

<%: Html.DisplayFor(m => m.SilverightSample) %>

This design does not currently have a way to make the Silverlight control full screen.

I have not needed a Silverlight control to be full screen so that is probably why I never added it. If you wanted to make it full screen you could just have a boolean for full screen and change the height and width to be 100% in your partial.

MVCSilverlightSample