This article is compatible with the latest version of Silverlight.
Introduction
In my last article I showed you how easily Silverlight can interact with the HTML DOM. Not only you can execute JavaScript functions from your Silverlight application, but you can also call Silverlight methods from JavaScript. This functionality enables you to create very powerful applications.
As you already know Silverlight runs in a sandbox. This is a special “place” limited for security reasons. It is part of the browser, so Silverlight runs in the browser. Here are some of the limitations of Silverlight:
- You have no direct access to the local resources like printers. You can use JavaScript to print your page.
- Silverlight does not have direct access to the file system. It has only access to the isolated storage area, where it can store data. This area is limited. Initially, it has size of 1MB per web site. It is possible to increase the size of this area after the user agreement.
- There is no way to open dialogs like Open/Save. You can only use the browser Open dialog (OpenFileDialog).
Silverlight is designed to work in disconnected areas. If you want to connect a server, you should open a new asynchronous connection. As working in the context of the browser Silverlight can easily interact with it. As you will see in the following examples, you can use a great variety of functions to access different browser features.
The Namespace
The namespace System.Windows.Browser contains all necessary objects to interact with the browser. You need to include this namespace in your project, before starting working. You need also to add this assembly as reference to your project.
Working with Bookmarks
What is a bookmark? You may connect this term with the Firefox bookmarks, for example, but in our case it has a different meaning. Bookmarks let the browser navigate to a part of the page. For example, you have a web page with many lines of text. You can set a bookmark to a specific part of this text and let the user see this part first. You can navigate to a bookmark using the following URL: http://www.mysite.com/mypage.aspx#mybookmark
With Silverlight you can access the requested bookmark very easily. Here is an example of this:
private void ProcessBookmark()
{
string bookmark = HtmlPage.Window.CurrentBookmark;
if (this.pages.ContainsKey(bookmark))
{
bContent.Background = new SolidColorBrush(this.pages[bookmark]);
}
}
I created a small application which consists of four buttons – each represents a different color. When you press a button, it changed the color of the content. By default, the content block is colored in gray. Using bookmarks you can directly set a color when loading the control. You can see the application online. If you open the following URL - http://www.silverlightshow.net/storage/demos/SilverlightAndBrowser/UsingBookmarks.html#Red, you will see the content block colored in red.
You are able to change the current bookmark, too. However, there is no a gallant way to do this. All you need to do is call a JavaScript code. How? I talked about invoking JavaScript functions in my previous article. Here is an example:
private void SetBookmark(string bookmark)
{
HtmlPage.Window.Eval(String.Format("window.location.hash='{0}'", bookmark));
}
Accessing the Query String
The query string gives you far more power. It provides a way to pass variables to the server via the URL. From Silverlight you can access the query string, too. Look at the following example:
private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
string name = HtmlPage.Document.QueryString["name"];
if (String.IsNullOrEmpty(name))
{
txtHello.Text = "Hello, Happy User!";
}
else
{
txtHello.Text = String.Format("Hello, {0}!", name);
}
}
In this example, our application reads the query string variable ‘name’ and shows its value to a text block. You can specify as many variables as you want. You can see this application online. You can set a query string variable in this way: http://www.silverlightshow.net/storage/demos/SilverlightAndBrowser/AccessingQueryString.html?name=pesho
The QueryString property can be found in a HtmlDocument object. It is a dictionary of type Dictionary<string, string> and allows you to access each variable, passed with the URL, by its key.
Working with Cookies
This is the most interesting part of the article. Cookies are nothing more than a text, which the server sends to the client (usually a browser). Than with each request the client sends back the cookies, which are associated with this server. Cookies are another approach for maintaining state (as you know, HTTP protocol does not support states). They are used for authentication, storing your shopping cart, indicating you have done something in the site, etc. Cookies are very useful and have a great usage.
Now, let’s have a look at the following application. It has a button, a list and a textbox. When you first start the application, the list is empty. When you press the button, two cookies are set, which expire after 15 minutes. After reloading the page, you see these cookies in the list. After selecting a cookie from the list, you can see its value in the textbox.
How to Get Cookies?
The way to work with cookies is not as simple as in ASP.NET, for example. But it is simple enough to let you set and retrieve them. To access the cookies, you call HtmlPage.Document.Cookies. However it is not a collection, but a string. You may ask, how to get all cookies from a string? Well, cookies are stored all in this string with a delimiter – ‘;’. So you need to split the cookies string in order to get all of them. Here is an example of this:
private List<Cookie> GetCookies()
{
string[] cookies = HtmlPage.Document.Cookies.Split(';');
List<Cookie> cookieList = new List<Cookie>();
foreach (string c in cookies)
{
cookieList.Add(new Cookie(c));
}
return cookieList;
}
The Cookie class is a helper class, created by me. It is like KeyValuePair<string, string>, but has predefined constructors.
You can even create an extension method of the HtmlDocument class, which returns the cookies in a friendlier way.
How to Set a Cookie?
The Cookies property of the HtmlDocument class is get-only. So how can we set a cookie? You may make association with the first example with the bookmarks. There we invoked a JavaScript function. Here we have to manipulate a special property of HTML document in order to set our cookie. You can see how this can be achieved with JavaScript. Here is an example for Silverlight:
public void SetCookie(string key, string value)
{
DateTime expireDate = DateTime.Now.Add(TimeSpan.FromMinutes(15));
string newCookie = String.Format("{0}={1};expires={2}", key, value, expireDate.ToString("R"));
HtmlPage.Document.SetProperty("cookie", newCookie);
}
In order to set a cookie, you need to change the cookie property of the HTML document. Because the HtmlDocument class does not contain such a property, you need to call the SetProperty method. Note also the format of the cookie. It must be in the following format: Key=Value;expires=ExpirationDate. The fields in bold are expected to be filled by you. The expiration date should in the following format: Thu, 17 Aug 2000 23:32:32 GMT. If you do not follow this format, your cookie will be set wrongly. If you do not specify an expiration date, the cookie will be present until you close the browser (end of your session). If you just set a string, which is not in this format, than the cookie will be set without a name and you cannot access it in a friendly way. Maybe this is the reason why the Silverlight team has decided not to create a dictionary property of type Dictionary<string, string> just like the QueryString. If you have a cookie without a name, you cannot access it from a key-based collection like the Dictionary.
Nikolay Raychev has written a great article about cookies in the web request. You have to read it.
How to Access the Browser Information
With JavaScript you can access the browser information very easily. Well, Silverlight has a more gallant way to do this. Here is the BrowserInformation class. In the HtmlPage static class, you can call the BrowserInformation property to get an instance of the BrowserInformation class. Here are the properties of this class:
- BrowserVersion – gets the browser version
- CookiesEnabled – checks if the cookies are enabled
- Name – gets the browser’s name
- Platform – gets the name of the operation system
- UserAgent – gets the user agent string of the browser
public void GetBrowserInformation()
{
StringBuilder sb = new StringBuilder();
BrowserInformation bi = HtmlPage.BrowserInformation;
sb.AppendFormat("Name: {0}\n", bi.Name);
sb.AppendFormat("Version: {0}\n", bi.BrowserVersion);
sb.AppendFormat("Platform: {0}\n", bi.Platform);
sb.AppendFormat("UserAgent: {0}\n", bi.UserAgent);
sb.AppendFormat("Cookies Enabled?: {0}\n", bi.CookiesEnabled);
HtmlPage.Window.Alert(sb.ToString());
}
Conclusion
You saw that with Silverlight not everything is so gallant, but everything can be achieved in one or another way. As a part of the browser, Silverlight has access to browser’s features and can use them.
In my next article I will show you how you can send data to the server using GET and POST. There are some tricks you should know in order to do this.
Source Code
You can download the source code of each example in the article.
References