ASP.NET MVC and Silverlight

I’m not going to dwelve too deep into Silverlight, as I’m just learning it  πŸ™‚  But one of the things I wanted to try out was using the Silverlight WebClient capability to call a Controller action (vs. a web service, etc…).  I’m treating Silverlight as a UI presentation layer – and letting my Controller/Actions be the glue to my existing service layer/data layer.

I used Scott Guthrie’s blog post as a guide to using the WebClient capability:

http://weblogs.asp.net/scottgu/pages/silverlight-tutorial-part-3-using-networking-to-retrieve-data-and-populate-a-datagrid.aspx

A few steps:

The Action – using XmlResult

I wanted the data returned from the Action to be xml.  Luckily, the MVCContrib includes a ‘XmlResult’ (ActionResult).  If you download the source you can see what it is doing.  A brief description: “…Action result that serializes the specified object into XML and outputs it to the response stream.”  Just want I want

Here is a quick example of the action I’m using:

public XmlResult XmlSquadronStats(string SquadId)
        {
            IPilotStatsDao pilotStatsDao = DaoFactory.GetPilotStatsDao();
            var stats = pilotStatsDao.GetAllPilotSummariesBySquad(SquadId);
            return new XmlResult(stats);
        }

 

Silverlight

With Silverlight, you cannot add a ‘non-Silverlight assembly’  – so in the above, I’ll be returning a List<PilotStats> – but I can’t just include the ‘PilotStat’ class in my domain object in silverlight.  That isn’t a bad thing however, as it will help me layer my Silverlight application.  So my first step is to create a new class, which I call PilotStat (see that above article by Scott Gu, I’m just taking that same concept and applying it here).

public class PilotStat
    {
        public string PilotName{get;set;}
        public int Missions{get;set;}
        public int Flights{get;set;}
        public int Kills{get;set;}
        public int Deaths{get;set;}
        public int Landed{get;set;}
        public int GroundTargets{get;set;}
        public int Crashes{get;set;}
        public int Bailed{get;set;}
        public int Captured{get;set;}
        public int ShotDown{get;set;}
        public int TanksDestroyed{get;set;}
        public int ShipsDestroyed{get;set;}
        public int Points{get;set;}
    }

Next, I want to work with my Page.xaml – to keep it simple, I want to use a querystring to pass to the page to determine which ‘squadrons’ data I want to load in the view.  This is the part of Silverlight I do like – it’s interaction with the underlying page.  So first I want to validate there is a querystring key/pair being used:

if (!System.Windows.Browser.HtmlPage.Document.QueryString.ContainsKey("SquadId"))
            {
                Status.Text = "Please provide SquadId";
            }

Next, I’m adding some code to make it easy to deploy later (this is really simple example!)

else
            {
                string squadId = System.Windows.Browser.HtmlPage.Document.QueryString["SquadId"];
                try
                {
                    Uri uri = Application.Current.Host.Source;
                    string host = uri.Host;

                    string statsUrl = string.Format("http://{0}/ForgottenWars/Squadron.mvc/XmlSquadronStats?SquadId={1}", host, squadId);
                    Status.Text = statsUrl;
                    WebClient client = new WebClient();
                    client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
                    client.DownloadStringAsync(new Uri(statsUrl));
                }
                catch (Exception ex)
                {
                    Status.Text += ex.Message;
                }
            }

Lastly, I want to display these results in the Datagrid:

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            DisplayStats(e.Result);
        }

        void DisplayStats(string xmlContent)
        {
            XDocument xmlStats = XDocument.Parse(xmlContent);
            var stats = from stat in xmlStats.Descendants("GetAllPilotSummariesBySquadResult")
                        select new PilotStat
                        {
                            PilotName = (string)stat.Element("PilotName"),
                            Missions = (int)stat.Element("Missions")
                        };
            PilotStatsGrid.ItemsSource = stats;
        }

I’m happy to report that this works well  πŸ™‚  I developed it on my Vista laptop with IIS 7 and was able to easily deploy the clientbin to my hosted IIS 6 server.

Although not rocket science here, I like the idea of being able to resuse my existing mvc architecture and adding this Silverlight UI on top of it. 

Feel free to send me any feedback on this approach!

Advertisements

4 thoughts on “ASP.NET MVC and Silverlight

  1. I discovered your blog online and read a few of your additional blogposts. I just added you to my Google News Reader. Maintain the great work. Look forward to reading much more of your stuff sometime soon.

  2. Yes, I have implemented something very similiar. The problem I am having is, when you try to save data back to the controller, the controller will not recognize the data unless the object it is decorated with ModelBinder or ActionFilterAttribute. Because these are found in the System.Web.Mvc libraries, I can’t use them in my Silverlight project. So I am left having to maintain two class files. One for Silverlight and one for the MVC web project. Have you found a solution for this?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s