Pass the IP Address of a User to Silverlight as a Parameter

In my beginning attempts to learn Silverlight, one of the first ideas for a project was to make a Silverlight video player that could change the source of the video file based on the location of the user.  The goal was to reduce network congestion between the branch offices back to the main office by having the Silverlight client download the media file from their local branch.  I wanted to give all users at the company the same URL to watch the video but the source of the video would actually change depending on the IP address of the user.  This is the problem I had:

How do I make Silverlight aware of the IP address of the user and then make that data available during the lifecycle of the Silverlight application?

It turns out that there are quite a few ways to accomplish this task, both in how to make the Silverlight client aware of the user’s IP address as well as how to make the variable accessible during the life of the application.

Before I go into the solution that I used, here are several resources I used to find my answer:

Getting the IP Address

I was a bit surprised to learn that there was no default method in Silverlight to get the IP Address of the current user.  Then I remembered that Silverlight is client technology and accordingly it would need to get the user’s IP address from outside of itself.  The easiest way (that I found) is to let the server that is hosting the application provide the IP address to the Silverlight client at startup.

If you looked at the answers in my first Stack Overflow question from above, you can see that some of the answers involve using JavaScript to directly modify a control within the Silverlight application.  While this is certainly possible, it seems a little complicated and I don’t want to have to create a control in Silverlight just to hold the IP address.  I found that using simple ASP.NET within the “initParams” parameters of the Silverlight object tag was the easiest method.  The code will look something like this:

Click to Enlarge

The “initParams” parameter can be used within the object tag of regular HTML or ASP.NET.  However, since I need the server to communicate the IP address to Silverlight in some way, I’m using ASP.NET (which is on the server) to pass the parameter into “initParams”.

<param name="initParams"
value="txtUserIP=<%=Request.UserHostAddress %>,cc=true,m=/relative"/>

If you were to click “View Source” after the page had loaded, you would see the actual IP address instead of the ASP tags.

Doing Something With InitParams Data

After we pass the IP Address into InitParams, we have to do something with the data on the Silverlight side.  My third question on Stack Overflow sought to find the answer to this question, but I found the best answer to be in Tim Heuer’s video on Silverlight.net.

The only place that InitParams are made available during the application lifecycle is at the application startup.  Specifically, you need to look in the code-behind of your App.xaml file (in my case, it was App.xaml.cs since I was using C#).  The Application_Startup method will look like this:

Click to Enlarge 

The InitParams are part of the StartupEventArgs e collection.  If we want to do something with the parameters in the main page, it will be important to insert our code before this.RootVisual = new MainPage();.

Storing the InitParams in a Resource Dictionary

While I certainly could create a public variable in my App.xaml.cs class, I liked Tim’s idea of using a resource dictionary.  He shows three different methods in his video demonstration, but the one I liked best was to simply pass the InitParams into the Application Resource Dictionary.  This way, the IP address will be available during the life of the application.

Click to Enlarge

A simple foreach loop will help us to add all of the InitParams to the Application’s Resource Dictionary.  You can then get the parameter value from the resource dictionary using App.Current.Resources[“txtUserIP”].ToString();.

Last Things

If you’re interested in how to hook up the source of a video to a media player in Silverlight, I recommend checking out the source code for the Silverlight 2 Video Player on Codeplex.  If you look in App.xaml.cs in the source code, you can see how they format a URI to be set as the source for the Media control.  You’ll need to use URI(txtURL, UriKind.RelativeOrAbsolute) if the link is external to your site and URI(txtURL, UriKind.Relative) if the link is in the same site.  The Media control’s source must be a URI, not just a string.

Also, the source of your media control cannot be a UNC path (e.g. //InternalServer/video.wmv) because Silverlight is sandboxed so that it does not recognize local resources.  If your Silverlight App is hosted in http, then the video must be an http source, and if it’s hosted in https, then the video must be an https source.  I had hoped to be able to simply pull video from a network share at each branch office, but because of this restriction, I would actually have to set up IIS (or some other web server) to host the videos at each site.

In regards to the IP address of the user, the IP address returned to Silverlight will only extend as far as the site on which it is hosted.  For example, if you run the Silverlight App from within your ASP.NET test hosting server on your local PC, you’ll probably get 127.0.0.1 (I think).  If it’s hosted on an IIS server behind your company’s firewall, you’ll get your internal IP address.  If the Silverlight App is hosted on a public website, you’ll get the user’s public IP address.

Lastly, make sure you video is encoded properly or else it won’t play in Silverlight.  I recommend using MS Expression Encoder to handle this task.