Wednesday, February 9, 2011

Injecting content into Silverlight OOB application

I recently came across an interesting problem in our Silverlight 4.0 application. The application has function to select a video to download from a catalog and then downloads it using a built in download manager. A request was made to allow our application to accept "injected" content from another website, without having to go through web services and databases. This article will explain the approach we took to inject content into the OOB application.

Approach:
The approach that was taken to inject content was to queue the injected content into the application's IsolatedStorage. When the application is accessed in browser, it shares the same isolated storage as accessed by the application when run in OOB mode. We therefore redirected the user the application within the browser and sent through a DownloadId parameter to the in-browser page, which then got written to the IsolatedStorage.  On startup of the application in OOB mode, the IsolatedStorage was then read from, firing off any downloads in the queue.

Step 1: Set up the web page to allow initParams to be accepted
Open the Web project in your Silverlight 4.0 OOB application. Open the Default.aspx page and locate the body section, where the parameters are listed.

Add the following parameter:

<param name="initParams" runat="server" id="prmInitParams" value="dummy=" />

Note: It is important to have a value set for this parameter. If no value is set, an error is thrown in the markup at runtime and you will not be able to use the application.


Step 2: Set the values in the code behind
Next step is to open the code behind file for this page (if there isn't one you'll need to create one before continuing).

In the Page_Load event handler, we then check if the QueryString contains a key called "DownloadId". If it does, we then set the value for the initParams key to contain the Key/Value pair, where the Key is set to a random Guid  - all we care about here is the value.


 protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (Request.QueryString.GetValues("DownloadId") != null)
                {
                    var downloadId = Request.QueryString["DownloadId"];
                    prmInitParams.Attributes["value"] = Guid.NewGuid() + "=" + downloadId;
                }
            }
            catch (Exception)
            {


            }
        }


Now that this parameter has been set, it is then automatically sent through to the Application_Startup method in your App.Xaml class as the InitParams property within the StartupEventArgs.


Step 3: Writing the injected files to isolated storage
The final step is to actually store these values into the IsolatedStorage. As mentioned above, the Application_Startup event is fed with the parameters sent through from our web page. These parameters can be accessed in the following way (within App.Xaml):


  private void Application_Startup(object sender, StartupEventArgs e)
        {
            if (!Application.Current.IsRunningOutOfBrowser)
            {
                var oldList = IsoStoreAppSettings.QueuedDownloadIDs;
                InjectedDownload ij = new InjectedDownload();
                foreach (var injectedValue in e.InitParams)
                {
                    ij.DownloadId = injectedValue.Value;
                    oldList.Add(ij);
                }
                IsoStoreAppSettings.QueuedDownloadIDs = oldList;
            }
        }

As you can see we have a helper class called IsoStoreAppSettings which is just a simple class that accesses the isolated storage in the following way:
IsolatedStorageSettings.ApplicationSettings["QueuedDownloadIDs"]

Final Step: Accessing the injected content in OOB application
The final step is to access the injected content from the application whilst running the application in OOB mode.
This is simple - all you need to do is loop through the parameters in your IsolatedStorage and work with them as needed, as depicted in the else block below:
  if (!Application.Current.IsRunningOutOfBrowser)
            {
                var oldList = IsoStoreAppSettings.QueuedDownloadIDs;
                InjectedDownload ij = new InjectedDownload();
                foreach (var injectedValue in e.InitParams)
                {
                    ij.DownloadId = injectedValue.Value;
                    oldList.Add(ij);
                }

                IsoStoreAppSettings.QueuedDownloadIDs = oldList;
            }
            else
            {
                foreach (var downloadId in IsoStoreAppSettings.QueuedDownloadIDs)
                {
                    StartDownload(downloadId);
                }
            }


No comments:

Post a Comment