Stephan Dekker

If you are out to describe the truth, leave elegance to the tailor. (Albert Einstein, 1879 - 1955)

December 2008 - Posts

Even though there are already a couple of blogposts about bookmarking pages from an asp.net environment using the AJAX scriptmanager, there are not a lot of people that have done deep linking with querystrings and silverlight apps hosted in HTML.

This feature is missing in the current version of silverlight (2.0) and needs to be implemented by hand, if you need to have it. A lot of business App need it, and so does ours.

The solution is an elegant one as well (If I may say so myself): Create a javascript method that gets called when the silverlight app starts, let the javascript method call a method on our silverlight app that's exposed to javascript and let that silverlight method parse the querystring into anything we want it to be!

So here we go:

  • Create an HTML host file to host the silverlight app. Make sure the object has an Id. In our case: SilverlightControlApp 

   66     <div id="silverlightControlHost">

   67         <object id="SilverlightControlApp" data="data:application/x-silverlight-2,"  <!-- Notice the ID -->

   68             type="application/x-silverlight-2" width="100%" height="100%">

   69             <param name="source" value="ClientBin/MyYetAgainVeryCoolDemoApp.xap"/>

   70             <param name="onerror" value="onSilverlightError" />

   71             <param name="onload" value="PassTheQueryStringToSilverlight" />    <!-- Notice the Event -->

   72             <param name="background" value="white" />

   73             <param name="minRuntimeVersion" value="2.0.31005.0" />

   74             <param name="autoUpgrade" value="true" />

   75             <a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">

   76                  <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>

   77             </a>

   78         </object>

   79         <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>

   80     </div>

  • Create a javascript file to contain the QueryStringRetrieval. I named it "QueryStringHelper.js".
  • paste the following method in there:

    2 function PassTheQueryStringToSilverlight(sender, args) {

    3     try     {

    4         silverlightControl = document.getElementById("SilverlightControlApp");

    5         silverlightControl.Content.SilverlightApp.SetQueryString(location.search);

    6     }

    7     catch (e) {

    8         alert("An exception occurred in the script. Error name: " + e.name

    9               + ". Error message: " + e.message);

   10     }

   11 }

 

  • Add the javascript reference in the HTML page:

   20     <script type="text/javascript" src="Silverlight.js"></script>   <!-- Generated by VS -->

   21     <script type="text/javascript" src="QueryStringHelper.js" />    <!-- Add this yourself -->

  • Add an OnLoad event handler to the Silerlight host object to call the javascript method. Notice the event in the HTML code above.
  • Open the App.xaml.cs and create a method to receive the queryString. Use the ScriptableMember to expose the member to be called from Silverlight.

   65         [ScriptableMember]

   66         public void SetQueryString(string queryString)

   67         {

   68             // Get the panel from the querystring

   69             var parms = QueryStringHelper.ParseQueryString(queryString);

   70             if (parms.ContainsKey("panel")) SetPanel(parms["panel"]);

   71         }

   72 

   73         private void SetPanel(String panel)

   74         {

   75             // Navigate to the specified panel

   76             if (_availablePanels.Contains(panel)) page.PanelToShow = panel;

   77         }

  • Register the class as scriptable in the HTML pages by calling HtmlPage.RegisterScriptableObject(String, Object); I've done it from the constructor in the App class in the App.xaml.cs. 

   20         public App()

   21         {

   22             HtmlPage.RegisterScriptableObject("SilverlightApp", this);

   23 

   24             Startup += Application_Startup;

   25             Exit += Application_Exit;

   26             UnhandledException += Application_UnhandledException;

   27 

   28             InitializeComponent();

   29         }

  •  Implement the querystring parsing. I re-used a piece of code from the almighty internet. Just create a class called QueryStringHelper and copy paste the following section code:

    2 using System;

    3 using System.Collections.Generic;

    4 using System.Text.RegularExpressions;

    5 

    6 namespace MyYetAgainVeryCoolDemoApp.Silverlight

    7 {

    8     public class QueryStringHelper

    9     {

   10         public static Dictionary<String, String> ParseQueryString(String queryString)

   11         {

   12             var result = new Dictionary<String, String>();

   13 

   14             // Source = http://increment.cx/wordpress/?p=106

   15             var regexPattern = @"\?(?<nv>(?<n>[^=]*)=(?<v>[^&]*)[&]?)*";

   16             var regex = new Regex(regexPattern, RegexOptions.ExplicitCapture);

   17             var match = regex.Match(queryString);

   18 

   19             for (var currentCapture = 0; currentCapture < match.Groups["nv"].Captures.Count; currentCapture++)

   20             {

   21                 result.Add(match.Groups["n"].Captures[currentCapture].Value.ToLower(),

   22                 match.Groups["v"].Captures[currentCapture].Value.ToLower());

   23             }

   24 

   25             return result;

   26         }

   27     }

   28 }

 And now, you'r ready to use query strings in your app!

Cheers mates!

 

Posted by Stephan Dekker | 2 comment(s)
Filed under: