<?xml version="1.0" encoding="utf-8" ?>
<!-- RSSProvider, for syndicating your content by Wilco Bauwer. --><!-- Feed last generated on: 05/07/2008 19:44:52 --><rss version="2.0">
<channel>
<title>Wilco Bauwer</title>
<link>http://wilcob.com/Wilco/View.aspx</link>
<description>Wilco Bauwer, a .NET orientated place.</description>
<managingEditor>wilco@wilcob.com</managingEditor>
<language>en-US</language>
<generator>Wilco's RSS Provider</generator>
<item>
<title>Threading in Silverlight</title>
<link>http://wilcob.com/Wilco/View.aspx?NewsID=216</link>
<pubDate>Thu, 17 Apr 2008 00:09:06 GMT</pubDate>
<description>&lt;div&gt;
	&lt;p&gt;Silverlight 2 brings support for threading to the browser. You can either directly start new threads using &lt;span class=&quot;inlineCode&quot;&gt;System.Threading.Thread&lt;/span&gt; and &lt;span class=&quot;inlineCode&quot;&gt;System.Threading.ThreadPool&lt;/span&gt;, or you can use the higher-level (and recommended) &lt;span class=&quot;inlineCode&quot;&gt;System.ComponentModel.BackgroundWorker&lt;/span&gt; type. The latter encapsulates the concept of executing work in the background (using a thread from the thread-pool) and updating the UI based on progress and/or completion of that work, which means that you can safely update the UI from the related events.&lt;/p&gt;

&lt;p&gt;A lesser-known type that we introduced in beta 1 is &lt;span class=&quot;inlineCode&quot;&gt;System.Windows.Threading.Dispatcher&lt;/span&gt;. This type lets you execute work on the UI thread - something that's useful when you directly want to update the UI from a background thread. Since Silverlight always has a single UI-thread, there is only a single disatcher instance per Silverlight application. This instance is accessible via any &lt;span class=&quot;inlineCode&quot;&gt;DependencyObject&lt;/span&gt; or &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt; instances' &lt;span class=&quot;inlineCode&quot;&gt;Dispatcher&lt;/span&gt; property. Once you have a reference to a dispatcher, you can use its &lt;span class=&quot;inlineCode&quot;&gt;BeginInvoke&lt;/span&gt; method to dispatch your work. In Silverlight we added an overload which takes an &lt;span class=&quot;inlineCode&quot;&gt;Action&lt;/span&gt;, which means you don't need to add a cast or anything to help the compiler infer what type of delegate you want to pass:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; myThread = &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; Thread(() =&amp;gt; {
    &lt;span style=&quot;color:#008000&quot;&gt;// Using a lambda...&lt;/span&gt;
    myTextBlock.Dispatcher.BeginInvoke(() =&amp;gt; myTextBlock.Text = &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Updated from a non-UI thread.&lt;/span&gt;&amp;quot;);

    &lt;span style=&quot;color:#008000&quot;&gt;// Using an anonymous delegate...&lt;/span&gt;
    myTextBlock.Dispatcher.BeginInvoke(&lt;span style=&quot;color:#0000FF&quot;&gt;delegate&lt;/span&gt; {
        myTextBlock.Text = &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Updated from a non-UI thread.&lt;/span&gt;&amp;quot;;
    });
});
myThread.Start();

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;Please note that you may not be able to find the dispatcher property via intellisense. It's marked as an advanced property, so you either need to update your VS settings to display advanced members, or you just need to ignore intellisense and assume your code will in fact compile regardless of what intellisense implies. The same goes for &lt;span class=&quot;inlineCode&quot;&gt;CheckAccess&lt;/span&gt;, which is actually marked as a member that should never be displayed. The main reason these members aren't always visible is because they shouldn't be as common as the other members on a &lt;span class=&quot;inlineCode&quot;&gt;DependencyObject&lt;/span&gt;. As I mentioned before, you'll probably want to use a &lt;span class=&quot;inlineCode&quot;&gt;BackgroundWorker&lt;/span&gt; most of the time instead.&lt;/p&gt;

&lt;h2&gt;Gotchas&lt;/h2&gt;

&lt;p&gt;There are a couple of things to be aware of. The first is that we try to guard against cross-thread invocations when this would potentially be unsafe. For example, we don't allow you to call into the HTML DOM or a JavaScript function from a background thread. The reason for this is that both assume to be invoked on the UI thread. Breaking this assumption can lead to unexpected behavior, including browser crashes.&lt;/p&gt;

&lt;p&gt;The other thing to be aware of is creating deadlocks. Silverlight comes with primitives such as &lt;span class=&quot;inlineCode&quot;&gt;Monitor&lt;/span&gt; (encapsulated via the lock construct in C#) and &lt;span class=&quot;inlineCode&quot;&gt;ManualResetEvent&lt;/span&gt; which make it trivial to create a deadlock. A deadlock will cause most browsers to hang completely. While technically this isn't very different from some JavaScript that infinitely, it's often easier to accidentally create a deadlock than an infinite loop of code. For example, I've seen several people try to create a synchronous version of &lt;span class=&quot;inlineCode&quot;&gt;HttpWebRequest&lt;/span&gt; by letting the current thread wait for a &lt;span class=&quot;inlineCode&quot;&gt;ManualResetEvent&lt;/span&gt; to be notified by the response callback. &lt;span class=&quot;inlineCode&quot;&gt;HttpWebRequests&lt;/span&gt; however execute their callbacks on the UI thread, which means you have a deadlock right there. While ideally you avoid blocking the UI thread entirely, you should at least consider specifying timeouts when you use a synchronization object. For example, instead of the &lt;span class=&quot;inlineCode&quot;&gt;lock&lt;/span&gt; construct in C# (&lt;span class=&quot;inlineCode&quot;&gt;Monitor.Enter/Exit&lt;/span&gt;), consider using &lt;span class=&quot;inlineCode&quot;&gt;Monitor.TryEnter/Exit&lt;/span&gt; passing in a reasonable timeout, and instead of using &lt;span class=&quot;inlineCode&quot;&gt;ManualResetEvent's&lt;/span&gt; parameterless &lt;span class=&quot;inlineCode&quot;&gt;WaitOne&lt;/span&gt;, consider using one of the overloads.&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
<title>HTTP requests in Silverlight</title>
<link>http://wilcob.com/Wilco/View.aspx?NewsID=215</link>
<pubDate>Mon, 14 Apr 2008 23:08:05 GMT</pubDate>
<description>&lt;div&gt;
	&lt;p&gt;There has been a fair amount of feedback regarding the &lt;span class=&quot;inlineCode&quot;&gt;HttpWebRequest&lt;/span&gt; type in Silverlight. People have asked or commented about:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The lack of support for synchronous requests;&lt;/li&gt;
  &lt;li&gt;Being limited to GET/POST requests;&lt;/li&gt;
  &lt;li&gt;No support for headers in GET requests;&lt;/li&gt;
  &lt;li&gt;Uploading large files;&lt;/li&gt;
  &lt;li&gt;Complexity of asynchronous requests.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The response to most of this feedback has been that we are limited by what functionality the browser provides to plugins. For example, the API implemented by all browsers but IE (called the NPAPI, short for Netscape Plugin API) basically has the following support for networking:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.mozilla.org/en/docs/NPN_GetURLNotify&quot; onclick=&quot;window.open('http://developer.mozilla.org/en/docs/NPN_GetURLNotify'); return false;&quot;&gt;NPN_GetURL(Notify)&lt;/a&gt;. Used to initiate a GET request. This API does not have support for passing in headers. There is also no synchronous version of this API.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.mozilla.org/en/docs/NPN_PostURLNotify&quot; onclick=&quot;window.open('http://developer.mozilla.org/en/docs/NPN_PostURLNotify'); return false;&quot;&gt;NPN_PostURL(Notify)&lt;/a&gt;. Used to initiate a POST request. This API optionally takes a buffer of in-memory POST data. There is no synchronous version of this API either.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You may be wondering why we were able to support synchronous requests in Silverlight 1.1 alpha, why it did support headers in GET requests, etc. In Silverlight 1.1 alpha we didn't use the aforementioned APIs. Instead, we essentially wrapped the browser's XMLHttpRequest object that you can use in JavaScript today via our HTML/JS bridge. This had a few disadvantages:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;No support for cross-domain requests.&lt;/li&gt;
  &lt;li&gt;Lack of support for dealing with binary data. We were able to get this working in FF, but Safari seemed to have problems handling responses beyond a certain size (couple of KB) wih binary data in them.&lt;/li&gt;
  &lt;li&gt;Since it depends on interoperability with JavaScript, it's not quite as efficient as directly using native APIs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There were a few things we could've done (and could still do) to deal with this. We could've used the operating system's networking stack and address most of the feedback we've had so far. The main disadvantage would be that all the requests would execute in their own security context. This means that if a user is authenticated using Windows authentication, any request sent by the Silverlight application would still be unauthenticated. Alternatively we could've created a hybrid, and choose what request type we would use based on the functionality you need. For example, if you don't care about binary data but you do care about headers in GET requests, we could use the browser's XMLHttpRequest object. But if you care about binary data and need authentication, we could use the browser's plugin API. Needless to say this would allow for a rather awkward/inconsistent programming experience.&lt;/p&gt;

&lt;p&gt;Until we find a better way to deal with all of these problems in a future release, you will unfortunately have to deal with these shortcomings. To help you out a little though, I've put together some code that basically does create some sort of hybrid between XMLHttpRequest and the current version of &lt;span class=&quot;inlineCode&quot;&gt;HttpWebRequest&lt;/span&gt; in Silverlight. In a nutshell, you can write code like this:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#008000&quot;&gt;// Based on the request uri, this will either return the Silverlight HttpWebRequest &lt;/span&gt;
&lt;span style=&quot;color:#008000&quot;&gt;// type (which supports binary data and cross-domain requests), or a HttpWebRequestEx &lt;/span&gt;
&lt;span style=&quot;color:#008000&quot;&gt;// type (which supports PUT/HEAD/etc, headers and synchronous requests).&lt;/span&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; request = HttpWebRequestEx.Create(requestUri);

&lt;span style=&quot;color:#008000&quot;&gt;// Assume we are requesting a resource on our server. Cast to HttpWebRequestEx &lt;/span&gt;
&lt;span style=&quot;color:#008000&quot;&gt;// such that we can call GetResponse for a synchronous request.&lt;/span&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; sameDomainRequest = (HttpWebRequestEx)request;
sameDomainRequest.Headers[&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;foo&lt;/span&gt;&amp;quot;] = &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;bar&lt;/span&gt;&amp;quot;;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; response = sameDomainRequest.GetResponse();
&lt;span style=&quot;color:#008000&quot;&gt;// ...&lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;I've also put together a type which might make it a little easier to work with HTTP requests. It's basically a wrapper around &lt;span class=&quot;inlineCode&quot;&gt;HttpWebRequestEx&lt;/span&gt; and &lt;span class=&quot;inlineCode&quot;&gt;HttpWebRequest&lt;/span&gt; and it is implemented as a &lt;a href=&quot;http://en.wikipedia.org/wiki/Fluent_interface&quot; onclick=&quot;window.open('http://en.wikipedia.org/wiki/Fluent_interface'); return false;&quot;&gt;fluent interface&lt;/a&gt; which should make it a little easier to construct a request:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;12 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;13 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;14 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#008000&quot;&gt;// Synchronous request.&lt;/span&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; response = Request.To(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;foo.txt&lt;/span&gt;&amp;quot;).Send().ReadAllText();
HtmlPage.Window.Alert(response);

&lt;span style=&quot;color:#008000&quot;&gt;// Asynchronous request with a header and POST data.&lt;/span&gt;
Request.To(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;foo.txt&lt;/span&gt;&amp;quot;)
    .WithMethod(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;POST&lt;/span&gt;&amp;quot;)
    .WithHeader(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;foo&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;bar&lt;/span&gt;&amp;quot;)
    .WithBody(writer =&amp;gt; writer.Write(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;hello&lt;/span&gt;&amp;quot;))
    .SendAsync(response =&amp;gt; HtmlPage.Window.Alert(response.ReadAllText()));

&lt;span style=&quot;color:#008000&quot;&gt;// Asynchronous, cross-domain request.&lt;/span&gt;
Request.To(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;http://services.digg.com/stories/topic/microsoft?count=3&amp;amp;appkey=http%3A%2F%2Fexample.com%2fapplication&lt;/span&gt;&amp;quot;)
    .SendAsync(response =&amp;gt; HtmlPage.Window.Alert(response.ReadAllText()));

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;You can download &lt;a href=&quot;http://wilcob.com/Wilco/Downloads/Programming/Wilco.Web.Silverlight.zip&quot;&gt;the sources and binaries&lt;/a&gt; to try this out yourself. Let me know what you think.&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
<title>Lighting Up Your AJAX Applications with Silverlight</title>
<link>http://wilcob.com/Wilco/View.aspx?NewsID=214</link>
<pubDate>Sat, 22 Mar 2008 01:03:12 GMT</pubDate>
<description>&lt;div&gt;
	&lt;p&gt;
During MIX this year Stefan Schackow did &lt;a href=&quot;http://sessions.visitmix.com/?selectedSearch=T10&quot; onclick=&quot;window.open('http://sessions.visitmix.com/?selectedSearch=T10'); return false;&quot;&gt;a presentation on the HTML/JS bridge in Silverlight 2&lt;/a&gt;. (It’s the second part of the presentation; the first part is Chung Webster talking about how you can use the ASP.NET controls to integrate Silveright in your web application.) If you’re interested, you can &lt;a href=&quot;http://wilcob.com/Wilco/Downloads/Programming/Lighting Up Your AJAX Applications with Silverlight - code.zip&quot;&gt;download the code for this session&lt;/a&gt; and see how things were done.
&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
<title>ASP.NET/Silverlight component development</title>
<link>http://wilcob.com/Wilco/View.aspx?NewsID=213</link>
<pubDate>Sun, 09 Mar 2008 20:29:37 GMT</pubDate>
<description>&lt;div&gt;
	&lt;p&gt;Almost all of the Silverlight demos you see out there are completely client-side, and invoke Web services to post/get data. This approach makes sense, but when you want to use Silverlight to functionally enhance your existing website, you may want to have some kind of integration between Silverlight objects and your server-side controls.&lt;/p&gt;

&lt;p&gt;You may also want to enable some kind of Silverlight object composition. For example, my &lt;a href=&quot;http://wilcob.com/Wilco/Silverlight/file-upload-component-for-Silverlight-and-ASP-NET.aspx&quot;&gt;AsyncFileUpload component&lt;/a&gt; has two visualizers. It should be easy to add a new visualizer without modifying any existing code.&lt;/p&gt;

&lt;p&gt;To address these problems, I’ve put together some experimental code.&lt;/p&gt;

&lt;h2&gt;Object composition&lt;/h2&gt;

&lt;p&gt;Each Silverlight instance has its own AppDomain. You can pass managed objects from one Silverlight instance to another through the &lt;a href=&quot;http://wilcob.com/Wilco/Silverlight/silverlight-interoperability.aspx&quot;&gt;HTML/JS bridge&lt;/a&gt;, but you would only be able to program against it like any other JavaScript object. The &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject.ManagedObject&lt;/span&gt; property for such an object would be null if the underlying managed object isn’t part of the current AppDomain. As a result, we ideally compose objects inside a single Silverlight application, such that we can directly reference other objects. For example, the visualizers for our &lt;span class=&quot;inlineCode&quot;&gt;AsyncFileUploader&lt;/span&gt; can each reference the actual uploader, handle its events, get a stream to files being uploaded, etc.&lt;/p&gt;

&lt;p&gt;By composing the objects inside a single Silverlight instance, we have to solve a new problem, which is visual composition. We are suddenly limited visually to a single 'canvas' if you will. I’ve addressed this to a certain extent by introducing a concept called viewports. Per Silverlight instance there can be one viewport, which will be set as the root visual. All visual objects will be added to this viewport. It’s up to the implementation of the viewport to handle how it adds the visual objects. For example, a &lt;span class=&quot;inlineCode&quot;&gt;StackViewPort&lt;/span&gt; may add all visuals sequentially. A &lt;span class=&quot;inlineCode&quot;&gt;GridViewPort&lt;/span&gt; on the other hand may add visuals to the grid based on information that was set server-side:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;ASP.NET:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;12 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;AsyncFileUploadVisualizer&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;ID&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;v1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;runat&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;UploaderID&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;AsyncFileUpload1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;AsyncFileUploadProgressVisualizer&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;ID&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;v2&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;runat&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;UploaderID&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;AsyncFileUpload1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;GridViewPort&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;ID&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;GridViewPort1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;runat&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;Height&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;200px&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;Width&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;100%&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#800000&quot;&gt;ColumnDefinitions&lt;/span&gt;&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;ColumnDefinition&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;Width&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;2*&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;ColumnDefinition&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;Width&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;1*&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#800000&quot;&gt;ColumnDefinitions&lt;/span&gt;&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#800000&quot;&gt;Locations&lt;/span&gt;&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;GridViewPortItem&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;ControlID&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;v1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;Column&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;GridViewPortItem&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;ControlID&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;v2&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;Column&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#800000&quot;&gt;Locations&lt;/span&gt;&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;GridViewPort&lt;/span&gt;&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;To do the actual composition on the client, we need a few things. We need is a loader which downloads all the right things. As I mentioned before, we want to be able to implement new components. Those components will be added to their own XAP. Our loader needs to download the XAPs for all the objects before those objects can be loaded.&lt;/p&gt;

&lt;p&gt;Once the loader has downloaded the XAPs, we have to load the main assembly from this XAP. We can do this by parsing the AppManifest’s XAML as a deployment object and then find the main assembly. In code this looks like:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;12 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;13 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;14 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;15 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;16 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;17 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;18 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;19 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;20 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;static&lt;/span&gt; Assembly LoadAssemblyFromStream(Stream xapStream) {
    &lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; appManifestString;
    &lt;span style=&quot;color:#0000FF&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; reader = &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; StreamReader(Application.GetResourceStream(&lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; StreamResourceInfo(xapStream, &lt;span style=&quot;color:#0000FF&quot;&gt;null&lt;/span&gt;), &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; Uri(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;AppManifest.xaml&lt;/span&gt;&amp;quot;, UriKind.Relative)).Stream)) {
        appManifestString = reader.ReadToEnd();
    }

    Assembly entryPointAssembly = &lt;span style=&quot;color:#0000FF&quot;&gt;null&lt;/span&gt;;
    Deployment deployment = (Deployment)XamlReader.Load(appManifestString);
    &lt;span style=&quot;color:#0000FF&quot;&gt;foreach&lt;/span&gt; (&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; part &lt;span style=&quot;color:#0000FF&quot;&gt;in&lt;/span&gt; deployment.Parts) {
        &lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; streamInfo = Application.GetResourceStream(&lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; StreamResourceInfo(xapStream, &lt;span style=&quot;color:#0000FF&quot;&gt;null&lt;/span&gt;), &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; Uri(part.Source, UriKind.Relative));
        Assembly assembly = part.Load(streamInfo.Stream);

        &lt;span style=&quot;color:#0000FF&quot;&gt;if&lt;/span&gt; (assembly.FullName.Split(',')[0].Equals(deployment.EntryPointAssembly)) {
            entryPointAssembly = assembly;
        }
    }

    xapStream.Close();
    &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; entryPointAssembly;
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;(This technique can be useful for any kind of loader. Be careful though about the consequences. For example, if someone can use your loader to load their own XAP, that XAP would essentially impersonate your XAP, and thus be able to access its isolated store, etc. Certain things may also not work, such as resources defined in the delay-loaded XAP.)&lt;/p&gt;

&lt;p&gt;After we’ve loaded all the right assemblies into the current AppDomain, we can instantiate every object. The easiest way to do this is if we would simply render XAML directly from our server-side controls. We can then just go through each piece of XAML and load it using the &lt;span class=&quot;inlineCode&quot;&gt;XamlReader&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;To allow references between objects, we need to first instantiate all the objects and register them with a unique (user-defined) name. We then need to notify the objects that all objects have been registered such that they can actually get a reference to other objects. The following interface captures this:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;interface&lt;/span&gt; ISilverlightObject {

    &lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; Name {
        &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt;;
    }

    &lt;span style=&quot;color:#0000FF&quot;&gt;void&lt;/span&gt; Initialize();
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;For visual composition we also need a way to add visuals to a viewport if there is one. We can add another interface to take care of this:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;interface&lt;/span&gt; IViewPort : ISilverlightObject {

    &lt;span style=&quot;color:#0000FF&quot;&gt;void&lt;/span&gt; AddVisual(ISilverlightObject visual);
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;All visuals can add themselves to the viewport if there is one by using this interface. The viewport should take care of the rest. Viewports can set themselves as the root visual if there isn’t one already. The non-visual objects don’t need to do anything special. They can just do their thing based on their property values and/or a call to their Initialize method.
Now that we have most of the client-side plumbing in place, let’s see what we can do to add some kind of integration with ASP.NET.&lt;/p&gt;

&lt;h2&gt;ASP.NET integration&lt;/h2&gt;

&lt;p&gt;So far we have a Silverlight application which is essentially a host for composite objects. To host this application, and also to group composite objects, I introduced a &lt;span class=&quot;inlineCode&quot;&gt;SilverlightDomain&lt;/span&gt; ASP.NET control. I also introduced a &lt;span class=&quot;inlineCode&quot;&gt;SilverlightObject&lt;/span&gt; base class which you implement for every Silverlight object. This base class will register its instances with the &lt;span class=&quot;inlineCode&quot;&gt;SilverlightDomain&lt;/span&gt; that its part of. During rendering, the &lt;span class=&quot;inlineCode&quot;&gt;SilverlightDomain&lt;/span&gt; will ask every registered &lt;span class=&quot;inlineCode&quot;&gt;SilverlightObject&lt;/span&gt; to render XAML.&lt;/p&gt;

&lt;p&gt;The &lt;span class=&quot;inlineCode&quot;&gt;SilverlightObject&lt;/span&gt; base type automatically renders a few things. Based on the value of its &lt;span class=&quot;inlineCode&quot;&gt;ClientClrNamespace&lt;/span&gt; and &lt;span class=&quot;inlineCode&quot;&gt;ClientTypeName&lt;/span&gt; properties it will render the tag-name. All properties marked with a &lt;span class=&quot;inlineCode&quot;&gt;SilverlightPropertyAttribute&lt;/span&gt; will be added to the XAML. It will also register callbacks for all of its events marked with the &lt;span class=&quot;inlineCode&quot;&gt;SilverlightEventAttribute&lt;/span&gt;. On the client those events do need to be marked with &lt;span class=&quot;inlineCode&quot;&gt;ScriptableMemberAttribute&lt;/span&gt;, such that our plumbing code can properly attach a handler to it which initiates the postback. When the client-side event is raised and a postback is initiated, our &lt;span class=&quot;inlineCode&quot;&gt;SilverlightObject’s&lt;/span&gt; &lt;span class=&quot;inlineCode&quot;&gt;RaisePostBackEvent&lt;/span&gt; method is invoked. By default it will try to invoke a public &lt;span class=&quot;inlineCode&quot;&gt;On&amp;lt;EventName&amp;gt;(EventArgs)&lt;/span&gt; method, if one exists. If you don’t want to have such a public method, or you want to raise a more complex event, you can override &lt;span class=&quot;inlineCode&quot;&gt;RaisePostBackEvent&lt;/span&gt; and manually raise an event.&lt;/p&gt;

&lt;p&gt;As I just mentioned, you need to implement a few abstract properties such as &lt;span class=&quot;inlineCode&quot;&gt;ClientClrNamespace&lt;/span&gt; and &lt;span class=&quot;inlineCode&quot;&gt;ClientTypeName&lt;/span&gt;. You also need to implement &lt;span class=&quot;inlineCode&quot;&gt;PackageUrl&lt;/span&gt;. The &lt;span class=&quot;inlineCode&quot;&gt;SilverlightObject&lt;/span&gt; type will automatically render these as part of the XAML it renders. On the client, our package loader will use these attributes to find out what packages need to be downloaded. It then removes those attributes such that it ends up with 'clean XAML' that the &lt;span class=&quot;inlineCode&quot;&gt;XamlReader&lt;/span&gt; can load the remaining XAML directly.&lt;/p&gt;
 
&lt;h2&gt;A Silverlight powered ASP.NET button&lt;/h2&gt;

&lt;p&gt;Although there’s usually not much point in using Silverlight just to render primitive controls such as a button, this does concisely illustrate what it takes to put together a simple ASP.NET component that uses Silverlight for rendering. Here’s the client-side code:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;12 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;13 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;14 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;15 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;16 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;17 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;18 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;19 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;class&lt;/span&gt; Button : System.Windows.Controls.Button, ISilverlightObject {

    [ScriptableMember(ScriptAlias = &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;click&lt;/span&gt;&amp;quot;)]
    &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;event&lt;/span&gt; EventHandler Click;

    &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; Button() {
        &lt;span style=&quot;color:#0000FF&quot;&gt;base&lt;/span&gt;.Click += SimpleButton_Click;
    }

    &lt;span style=&quot;color:#0000FF&quot;&gt;void&lt;/span&gt; SimpleButton_Click(&lt;span style=&quot;color:#0000FF&quot;&gt;object&lt;/span&gt; sender, RoutedEventArgs e) {
        &lt;span style=&quot;color:#0000FF&quot;&gt;if&lt;/span&gt; (Click != &lt;span style=&quot;color:#0000FF&quot;&gt;null&lt;/span&gt;) {
            Click(sender, e);
        }
    }

    &lt;span style=&quot;color:#0000FF&quot;&gt;void&lt;/span&gt; ISilverlightObject.Initialize() {
        App.Current.LoadVisual(&lt;span style=&quot;color:#0000FF&quot;&gt;this&lt;/span&gt;);
    }
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;And the server-side code looks like this:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;12 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;13 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;14 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;15 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;16 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;17 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;18 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;19 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;20 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;21 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;22 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;23 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;24 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;25 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;26 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;27 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;28 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;29 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;30 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;31 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;32 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;33 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;34 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;35 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;36 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;37 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;38 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;39 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;40 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;41 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;42 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;43 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;44 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;45 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;46 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;47 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;48 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;49 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;50 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;51 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;52 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;53 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;54 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;55 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;56 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;57 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;class&lt;/span&gt; Button : SilverlightObject {

    &lt;span style=&quot;color:#0000FF&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;internal&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; ClientClrNamespace {
        &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt; {
            &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;clr-namespace:Wilco.Windows.Browser;assembly=Wilco.Windows.Browser&lt;/span&gt;&amp;quot;;
        }
    }

    &lt;span style=&quot;color:#0000FF&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;internal&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; ClientTypeName {
        &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt; {
            &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Button&lt;/span&gt;&amp;quot;;
        }
    }

    &lt;span style=&quot;color:#0000FF&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;internal&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; PackageUrl {
        &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt; {
            &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; Page.ClientScript.GetWebResourceUrl(&lt;span style=&quot;color:#0000FF&quot;&gt;typeof&lt;/span&gt;(Button), &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Wilco.Web.Silverlight.Resources.Wilco.Windows.Browser.xap&lt;/span&gt;&amp;quot;);
        }
    }

    [SilverlightProperty(ClientPropertyName=&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Background&lt;/span&gt;&amp;quot;, Converter=&lt;span style=&quot;color:#0000FF&quot;&gt;typeof&lt;/span&gt;(SilverlightColorConverter))]
    &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; Color BackgroundColor {
        &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt;;
        &lt;span style=&quot;color:#0000FF&quot;&gt;set&lt;/span&gt;;
    }

    [SilverlightProperty(ClientPropertyName=&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Content&lt;/span&gt;&amp;quot;)]
    &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; Text {
        &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt;;
        &lt;span style=&quot;color:#0000FF&quot;&gt;set&lt;/span&gt;;
    }

    [DefaultValue(0), SilverlightProperty]
    &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;int&lt;/span&gt; Height {
        &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt;;
        &lt;span style=&quot;color:#0000FF&quot;&gt;set&lt;/span&gt;;
    }

    [DefaultValue(0), SilverlightProperty]
    &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;int&lt;/span&gt; Width {
        &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt;;
        &lt;span style=&quot;color:#0000FF&quot;&gt;set&lt;/span&gt;;
    }

    [SilverlightEvent(ClientEventName = &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;click&lt;/span&gt;&amp;quot;)]
    &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;event&lt;/span&gt; EventHandler Click;

    &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; Button() {
        &lt;span style=&quot;color:#008000&quot;&gt;//&lt;/span&gt;
    }

   &lt;span style=&quot;color:#0000FF&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;void&lt;/span&gt; RaisePostBackEvent(&lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; eventArgument) {
        &lt;span style=&quot;color:#0000FF&quot;&gt;if&lt;/span&gt; (Click != &lt;span style=&quot;color:#0000FF&quot;&gt;null&lt;/span&gt;) {
            Click(&lt;span style=&quot;color:#0000FF&quot;&gt;this&lt;/span&gt;, EventArgs.Empty);
        }
    }
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;To use this on our page, we can write the following code in ASP.NET:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;ASP.NET:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;SilverlightDomain&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;runat&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;Button&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;ID&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;button1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;runat&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;BackgroundColor&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;Red&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;OnClick&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;button_Click&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;Text&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;Button 1&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;GridViewPort&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;runat&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;Height&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#FF0000&quot;&gt;Width&lt;/span&gt;=&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;quot;100%&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#C71585&quot;&gt;wilco&lt;/span&gt;:&lt;span style=&quot;color:#800000&quot;&gt;SilverlightDomain&lt;/span&gt;&lt;span style=&quot;color:#0000FF&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;To see a demo of this, go to &lt;a href=&quot;http://wilcob.com/Silverlight2/ViewPorts&quot; onclick=&quot;window.open('/Silverlight2/ViewPorts'); return false;&quot;&gt;this page with a few Silverlight buttons on it&lt;/a&gt;. For the source code, you can download &lt;a href=&quot;http://wilcob.com/Wilco/Downloads/Programming/Wilco.Web.Silverlight.zip&quot;&gt;Wilco.Web.Silverlight.zip&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
<title>File upload component for Silverlight and ASP.NET</title>
<link>http://wilcob.com/Wilco/View.aspx?NewsID=212</link>
<pubDate>Fri, 07 Mar 2008 19:28:59 GMT</pubDate>
<description>&lt;div&gt;
	&lt;p&gt;A little less than a year ago I wrote about &lt;a href=&quot;http://wilcob.com/Wilco/Silverlight/silverlight_asyncfileupload.aspx&quot; onclick=&quot;window.open('/Wilco/Silverlight/silverlight_asyncfileupload.aspx'); return false;&quot;&gt;an AsyncFileUpload component for Silverlight/ASP.NET&lt;/a&gt;. Several things have happened since then, so I decided to rewrite it and address some of the limitations it had along the way. To make sure we’re on the same page, let me outline the goals of this proof-of-concept:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Demonstrate how &lt;strong&gt;OpenFileDialog&lt;/strong&gt; and &lt;strong&gt;HttpWebRequest&lt;/strong&gt; can be used to upload (large) files.&lt;/li&gt;
  &lt;li&gt;Show how &lt;strong&gt;isolated storage&lt;/strong&gt; can be used to enable file resumes (even across browsers on the same machine).&lt;/li&gt;
  &lt;li&gt;Share some experimental object model to simplify &lt;strong&gt;ASP.NET/Silverlight component development&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The only real non-goal is building a file upload component of production-quality.&lt;/p&gt;

&lt;h2&gt;The result&lt;/h2&gt;

&lt;img src=&quot;/wilco/uploads/images/screenshots/asyncfileupload.png&quot; style=&quot;float: right; margin-left: 20px; margin-bottom: 10px&quot; /&gt;

&lt;p&gt;There are a few different demos you can take a look at:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://wilcob.com/Silverlight2/AsyncFileUpload&quot; onclick=&quot;window.open(this.href); return false;&quot;&gt;AsyncFileUpload with the default template&lt;/a&gt; (pure HTML visualization);&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wilcob.com/Silverlight2/AsyncFileUpload/CustomTemplate.aspx&quot; onclick=&quot;window.open(this.href); return false;&quot;&gt;AsyncFileUpload with a custom template&lt;/a&gt; (includes two Silverlight visualizers);&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wilcob.com/Silverlight2/ClientServices&quot; onclick=&quot;window.open(this.href); return false;&quot;&gt;AsyncFileUpload used from JavaScript&lt;/a&gt;. Although this demo still uses ASP.NET, you could easily do the same thing from other languages/frameworks/web-servers as well.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can also &lt;a href=&quot;http://wilcob.com/Wilco/Downloads/Programming/Wilco.Web.Silverlight.zip&quot;&gt;download the source code&lt;/a&gt; for the actual library behind all of this.&lt;/p&gt;

&lt;h2&gt;Uploading large files&lt;/h2&gt;

&lt;p&gt;Silverlight 2’s HttpWebRequest buffers the request data in memory entirely, because the underlying API it uses (provided by the browser) doesn’t support streaming. This means that – at least at the time of writing – you can’t just upload large files.&lt;/p&gt;

&lt;p&gt;We can work around this by uploading files in chunks. It does mean we need some special handling on the server, but a basic implementation requires little effort. We just need to make sure we send some meta-data with each chunk, such that the server knows where a chunk is supposed to go. There is some overhead involved here, but we can make up for this by showing accurate and visual feedback.&lt;/p&gt;

&lt;p&gt;By sending chunks to the server, we get support for resumes almost for free. All we need to do is keep track of some information, such as something that identifies a file and the location of the next chunk we need to send. When we store this information in isolated storage, we can use it from every browser on the user’s machine. This means you can resume uploading a file in any of the installed browsers, even if you uploaded part of the file in a different browser.&lt;/p&gt;

&lt;p&gt;While we’re uploading chunks to the server, we know exactly how much we’ve progressed and how much there is left. We can also easily find out how fast we’re uploading. This data can be used to give feedback to the user about the progress, speed, anticipated time left, and so forth.&lt;/p&gt;

&lt;p&gt;On the server we need to know a few things per chunk:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Something that identifies the file;&lt;/li&gt;
  &lt;li&gt;Something that identifies the user;&lt;/li&gt;
  &lt;li&gt;The chunk’s location;&lt;/li&gt;
  &lt;li&gt;The actual data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we have this information, we can process each chunk fairly easily. We could additionally return a checksum of the file and verify on the client that the server processed the right data. If it didn’t, the client could try resending the chunk.
After the client is done uploading, it could submit a form to the server. On the server you would again need something that identifies the user (such as a session ID) to find out what exactly has been uploaded.&lt;/p&gt;

&lt;h2&gt;ASP.NET/Silverlight component development&lt;/h2&gt;

&lt;p&gt;I will go over this in a separate post, probably tomorrow.&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
<title>Isolatated storage in Silverlight</title>
<link>http://wilcob.com/Wilco/View.aspx?NewsID=211</link>
<pubDate>Thu, 06 Mar 2008 19:36:29 GMT</pubDate>
<description>&lt;div&gt;
	&lt;h2&gt;Increasing quotas&lt;/h2&gt;

&lt;p&gt;Isolated storage is a facility that lets you read/write (transient) data without worrying about other applications accessing this data. We first introduced this in Silverlight about a year ago with the alpha release. Its support was fairly basic though, and you couldn't store more than 1mb of data per application.
We have given this feature an upgrade in Silverlight 2 beta 1. Although the default limit is &lt;em&gt;less&lt;/em&gt; than it was before (100kb instead of 1mb), you can now ask the user for a larger quota. You can do this by calling &lt;span class=&quot;inlineCode&quot;&gt;IsolatedStorageFile.TryIncreaseQuotaTo(long)&lt;/span&gt;:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;void&lt;/span&gt; OnMouseLeftButtonDown(…) {
    &lt;span style=&quot;color:#0000FF&quot;&gt;using&lt;/span&gt; (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
        &lt;span style=&quot;color:#0000FF&quot;&gt;if&lt;/span&gt; (store.TryIncreaseQuotaTo(&lt;span style=&quot;color:#008000&quot;&gt;/* 2mb */&lt;/span&gt; 2 * 1024 * 1024)) {
            &lt;span style=&quot;color:#008000&quot;&gt;// The user accepted our request.&lt;/span&gt;
        }
        &lt;span style=&quot;color:#0000FF&quot;&gt;else&lt;/span&gt; {
            &lt;span style=&quot;color:#008000&quot;&gt;// Quota not increased… Deal with it.&lt;/span&gt;
        }
    }
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;This method can only be called from a Silverlight initiated action, such as a mouse-down event on a WPF object. There's no cross-browser way to tell if a user clicked on a HTML object, so unfortunately this isn't supported. We decided to only support TryIncreaseQuotaTo in response to user-initiated actions because without this restriction an app could ask for more data at arbitrary, unexpected moments. This can be both annoying and unsafe – a user could accidentally accept a request for a larger quota if the dialog suddenly takes away focus.&lt;/p&gt;

&lt;p&gt;Silverlight will only ask the user for one of the pre-defined quotas: 100kb, 1mb, 5mb, 10mb or unlimited. This means that if you ask for 2mb, the user will actually be asked for 5mb. We do this to avoid asking the user every other second if it's ok to increase the quota by another few bytes - something the average user probably wouldn't understand.&lt;/p&gt;

&lt;h2&gt;Level of isolation&lt;/h2&gt;

&lt;p&gt;Each Silverlight application gets its own isolated store. This means that if you have two applications in the same directory, they will each get their own isolated store. This store will be accessible from every browser that's supported by Silverlight, which means you can write data in FF and read back this data in IE.&lt;/p&gt;

&lt;p&gt;We considered using isolation per page that hosts a Silverlight application. Unfortunately this doesn't work well in shared hosting scenarios. A page at www.contoso.com/joe/foo.html can have an iframe with www.contoso.com/john/bar.html in it, and access its DOM. This means it can inject its own Silverlight application into that DOM, and thus get access to the isolated store of the other website on the same domain.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://www.w3.org/html/wg/html5/&quot; onclick=&quot;window.open('http://www.w3.org/html/wg/html5/'); return false;&quot;&gt;HTML 5 spec&lt;/a&gt; runs into exactly this problem as well. For this type of scenario it recommends you simply do not use offline storage. Given the fact that by default you can't just execute your own code within a different Silverlight application's application domain, Silverlight should not be prone to this kind of cross-site attack.&lt;/p&gt;

&lt;p&gt;There is a downside to Silverlight's implementation though. When hosting a Silverlight application on a server and letting third-party websites add this to their page, they would all share the same isolated store. This might not be desirable. You could work around this by using URL rewriting on the server, but you need to be careful about the potential security implications this can have.&lt;/p&gt;

&lt;p&gt;Finally, while isolated stores are shared per application, quotas are shared per domain. This is done in anticipation of a configuration dialog we will likely be adding in a future build. Having quotas per application rather than per domain means it would make configuration a lot harder for users.&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
<title>Silverlight interoperability</title>
<link>http://wilcob.com/Wilco/View.aspx?NewsID=210</link>
<pubDate>Wed, 05 Mar 2008 22:49:03 GMT</pubDate>
<description>&lt;div&gt;
	&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;By now you’ve probably read a thing or two about &lt;a href=&quot;http://www.silverlight.net&quot; onclick=&quot;window.open('http://www.silverlight.net'); return false;&quot;&gt;Silverlight 2&lt;/a&gt;
already. About the layout system, the new set of built-in controls, data-binding, styles, templates, &lt;i&gt;yada yada&lt;/i&gt;. You may either already be cranking out code 
utilizing all of these visually-oriented features, or you may be left wondering:&lt;/p&gt;

&lt;p class=&quot;quote&quot;&gt;&amp;quot;How is any of this useful to me? I’m already using HTML/CSS/JS on the client, and I don’t have any intentions to visually enhance or replace 
my website.&amp;quot;&lt;/p&gt;

&lt;p&gt;My goal is to demonstrate how you can take advantage of Silverlight by taking you through some of the features in Silverlight that you can use to enhance your existing 
website in a &lt;em&gt;non-obtrusive&lt;/em&gt; way. Think:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Writing new code in a &lt;strong&gt;managed language&lt;/strong&gt; (C#, Ruby, JScript.NET, &lt;em&gt;whatever&lt;/em&gt;) instead of native (interpreted) JavaScript.&lt;/li&gt;
  &lt;li&gt;Using &lt;strong&gt;OpenFileDialog&lt;/strong&gt; to read files on the client, without round-tripping to the server.&lt;/li&gt;
  &lt;li&gt;Storing transient data securely on the client in &lt;strong&gt;isolated storage&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;Improving responsiveness and performance by executing work in the background through a &lt;strong&gt;BackgroundWorker&lt;/strong&gt; or by using ordinary &lt;strong&gt;threads&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;Accessing cross-domain data via the &lt;strong&gt;networking APIs&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;Retrieving real-time data from the server via &lt;strong&gt;sockets&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;Binding data by re-using WPF's &lt;strong&gt;data-binding engine&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’re wondering what the point of all &lt;em&gt;this&lt;/em&gt; is, ask yourself (or the users of your website) when the last time is you (or they):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;had no idea how much time there was left before an upload would finish;&lt;/li&gt;
  &lt;li&gt;couldn’t resume from a failed upload;&lt;/li&gt;
  &lt;li&gt;lost data (article/comment/etc.) after trying to save it;&lt;/li&gt;
  &lt;li&gt;wasted lots of server-side bandwidth (and decreased client-side responsiveness) because the server had to act as a proxy between the client and a third-party website.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This can be addressed with Silverlight. The key to integrating all of this is the two-way interoperability layer in Silverlight (sometimes referred to as 'the HTML/JS 
bridge'), which is what I will be going through in this article. I will show you how you can access the HTML DOM and use your existing JavaScript code. You will see how you can 
pass managed objects back and forth, and program against them in JavaScript like ordinary JS objects. We will dive deep and take a look at what really happens under the hood to 
understand how far exactly our interoperability goes.&lt;/p&gt;

&lt;h2&gt;Getting started&lt;/h2&gt;

&lt;h3&gt;Accessing the HTML DOM&lt;/h3&gt;

&lt;p&gt;Silverlight’s gateway to the browser is &lt;span class=&quot;inlineCode&quot;&gt;System.Windows.Browser.HtmlPage&lt;/span&gt;. It’s a static type with properties – such as &lt;span class=&quot;inlineCode&quot;&gt;Window&lt;/span&gt;, 
&lt;span class=&quot;inlineCode&quot;&gt;Document&lt;/span&gt; and &lt;span class=&quot;inlineCode&quot;&gt;Plugin&lt;/span&gt; – which should all be self-explanatory. The only thing to note is the &lt;span class=&quot;inlineCode&quot;&gt;IsEnabled&lt;/span&gt; 
property. Access to the hosting page may be disabled in a few situations:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The hosting page set the &lt;span class=&quot;inlineCode&quot;&gt;enableHtmlAccess&lt;/span&gt; hosting parameter to &lt;span class=&quot;inlineCode&quot;&gt;false&lt;/span&gt;. This is a common thing to
  do when hosting advertisements or other Silverlight content that you don’t trust.&lt;/li&gt;
  &lt;li&gt;Your code executes within a custom host, such as the Blend designer.&lt;/li&gt;
  &lt;li&gt;The plugin unloaded itself, either by removing itself from the HTML DOM, or by changing its &lt;span class=&quot;inlineCode&quot;&gt;source&lt;/span&gt; property.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Generally you’ll check for this flag before initializing code that uses &lt;span class=&quot;inlineCode&quot;&gt;HtmlPage&lt;/span&gt;, and bail out quickly if it returns &lt;span class=&quot;inlineCode&quot;&gt;false&lt;/span&gt;. 
There’s usually no need to check for this flag throughout the rest of your code.&lt;/p&gt;

&lt;p&gt;With this information it should be straightforward to access the HTML DOM. To insert a new element into the DOM, you may previously have written:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;JavaScript:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; element = &lt;span style=&quot;color:#0000FF&quot;&gt;document&lt;/span&gt;.createElement(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;div&lt;/span&gt;&amp;quot;);
element.innerHTML = &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Hello, World!&lt;/span&gt;&amp;quot;;
&lt;span style=&quot;color:#0000FF&quot;&gt;document&lt;/span&gt;.body.appendChild(element);

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;This translates to the following in C#:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; element = HtmlPage.Document.CreateElement(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;div&lt;/span&gt;&amp;quot;);
element.SetAttribute(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;innerHTML&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Hello, World!&lt;/span&gt;&amp;quot;);
HtmlPage.Document.Body.AppendChild(element);

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;You get the idea.&lt;/p&gt;

&lt;p&gt;A common thing you may run into is that when the plugin is initializing (the application's constructor executes), the HTML DOM may not be ready yet. This means you may not be able 
to find an element, or you may run into 'Operation aborted' errors in IE. To deal with this, you are encouraged to check for &lt;span class=&quot;inlineCode&quot;&gt;HtmlPage.Document.IsReady&lt;/span&gt; and
handle &lt;span class=&quot;inlineCode&quot;&gt;HtmlPage.Document.DocumentReady&lt;/span&gt; if the document isn't already ready.&lt;/p&gt;

&lt;h3&gt;Invoking JavaScript&lt;/h3&gt;

&lt;p&gt;Calling into JavaScript isn't much more complicated. To continue getting right to the point, let's take the following JavaScript:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;JavaScript:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; calculator = &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; Calculator(); &lt;span style=&quot;color:#008000&quot;&gt;// Assume this is a JS library of ours.&lt;/span&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; sum = calculator.add(5, 1);
&lt;span style=&quot;color:#0000FF&quot;&gt;alert&lt;/span&gt;(sum);

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;And turn it into C#:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; calculator = HtmlPage.Window.CreateInstance(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Calculator&lt;/span&gt;&amp;quot;);
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; sum = Convert.ToInt32(calculator.Invoke(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;add&lt;/span&gt;&amp;quot;, 5, 1));
HtmlPage.Window.Alert(sum.ToString());

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;There are a couple of things going on here.&lt;/p&gt;

&lt;p&gt;The first thing to notice is that you use &lt;span class=&quot;inlineCode&quot;&gt;HtmlWindow.CreateInstance&lt;/span&gt; to instantiate JavaScript objects. Under the hood this will evaluate some JavaScript to create the
instance, due to lack of native support for instantiating objects through the browser's plugin API.&lt;/p&gt;

&lt;p&gt;Next, notice that &lt;span class=&quot;inlineCode&quot;&gt;Window&lt;/span&gt;, an &lt;span class=&quot;inlineCode&quot;&gt;HtmlWindow&lt;/span&gt; type, has an &lt;span class=&quot;inlineCode&quot;&gt;Invoke&lt;/span&gt; method. It inherits this method from one 
of its base types, &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt;. A few other fundamental methods it inherited are &lt;span class=&quot;inlineCode&quot;&gt;InvokeSelf&lt;/span&gt;, &lt;span class=&quot;inlineCode&quot;&gt;GetProperty&lt;/span&gt; 
and &lt;span class=&quot;inlineCode&quot;&gt;SetProperty&lt;/span&gt;. These few methods let you do just about anything. I will cover them in-depth later in this article. For now all you need to remember is that these members
let you get and set values, and invoke functions.&lt;/p&gt;

&lt;p&gt;The other thing to notice is the call to &lt;span class=&quot;inlineCode&quot;&gt;Alert&lt;/span&gt;. We could've actually called into &lt;span class=&quot;inlineCode&quot;&gt;alert&lt;/span&gt; like this:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
HtmlPage.Window.Invoke(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;alert&lt;/span&gt;&amp;quot;, sum);

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;In fact, that's exactly what &lt;span class=&quot;inlineCode&quot;&gt;HtmlWindow.Alert&lt;/span&gt; does under the hood. In general we decided to make commonly-used functions first-class for discoverability and sometimes 
performance reasons. Whenever there is a built-in way to do something, you'll want to use that instead of using late-bound calls.&lt;/p&gt;

&lt;p&gt;Lastly, Invoke and &lt;span class=&quot;inlineCode&quot;&gt;GetProperty&lt;/span&gt; both have an &lt;span class=&quot;inlineCode&quot;&gt;Object&lt;/span&gt; return type. They may return a &lt;span class=&quot;inlineCode&quot;&gt;bool&lt;/span&gt;, 
&lt;span class=&quot;inlineCode&quot;&gt;double&lt;/span&gt;, &lt;span class=&quot;inlineCode&quot;&gt;string&lt;/span&gt; or &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt;. We always return a double for numbers because this is what Safari gives 
us back under the hood. Also, for now assume that &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt; is an ordinary JavaScript object.&lt;/p&gt;

&lt;p&gt;With this knowledge you should be able to do just about anything from managed code already. You can instantiate objects, invoke functions that return objects, set properties on those objects, 
and so forth. &lt;/p&gt;

&lt;p&gt;At this point you may be wondering what happens when you pass a managed object to JavaScript. Before we go into this, let's quickly go over the opposite of what we've done so far.&lt;/p&gt;

&lt;h3&gt;Invoking managed code&lt;/h3&gt;

&lt;p&gt;Before you can invoke any managed code from JavaScript, you first need to register the objects you want to expose to the browser. You also need to mark which members are callable with the 
&lt;span class=&quot;inlineCode&quot;&gt;ScriptableMemberAttribute&lt;/span&gt;, or mark all declared members at once with &lt;span class=&quot;inlineCode&quot;&gt;ScriptableTypeAttribute&lt;/span&gt;:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;12 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;13 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;14 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;15 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;16 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;17 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;18 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;19 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;class&lt;/span&gt; Calculator {

    [ScriptableMember]
    &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;int&lt;/span&gt; Add(&lt;span style=&quot;color:#0000FF&quot;&gt;int&lt;/span&gt; a, &lt;span style=&quot;color:#0000FF&quot;&gt;int&lt;/span&gt; b) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; a + b;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#008000&quot;&gt;// Not callable from script.&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;int&lt;/span&gt; Subtract(&lt;span style=&quot;color:#0000FF&quot;&gt;int&lt;/span&gt; a, &lt;span style=&quot;color:#0000FF&quot;&gt;int&lt;/span&gt; b) {
    &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; a – b;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}

&lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;class&lt;/span&gt; App : Application {

&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; App() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HtmlPage.RegisterScriptableObject(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;calc&lt;/span&gt;&amp;quot;, &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; Calculator());
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;After you have a scriptable object, you can use it from
JavaScript:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;JavaScript:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;12 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;void&lt;/span&gt; onPluginLoaded(plugin) {
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; calc = plugin.content.calc;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#008000&quot;&gt;// If you are using ASP.NET AJAX to create a Silverlight instance, use this instead:&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#008000&quot;&gt;// var calc = plugin.get_element().content.calc;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; sum = calc.Add(5, 1); &lt;span style=&quot;color:#008000&quot;&gt;// Case sensitive.&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;alert&lt;/span&gt;(sum);
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;try&lt;/span&gt; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; calc.Subtract(5, 1); &lt;span style=&quot;color:#008000&quot;&gt;// Failure. There's no such member.&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style=&quot;color:#0000FF&quot;&gt;catch&lt;/span&gt; (e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;alert&lt;/span&gt;(e.message ? e.message : e);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;As with calling into JavaScript from managed code, you can pass JavaScript objects and DOM elements to managed code, assuming the signature of the invoked member permits this.&lt;/p&gt;

&lt;p&gt;You should make sure you don't access any managed objects before they're initialized. If you need to access them when the page is loaded, you should handle the plugin's 
&lt;span class=&quot;inlineCode&quot;&gt;onload&lt;/span&gt; event and access your managed objects from there.&lt;/p&gt;

&lt;h2&gt;Inside the marshalling layer&lt;/h2&gt;

&lt;p&gt;So far the examples we've seen are very basic. They involve calling methods with primitive arguments and return values. In Silverlight our support goes much further however. As I 
briefly mentioned before, you can pass arbitrary managed objects back and forth between Silverlight and the browser. We also have specialized support for &lt;span class=&quot;inlineCode&quot;&gt;DateTimes&lt;/span&gt;, 
&lt;span class=&quot;inlineCode&quot;&gt;Guids&lt;/span&gt;, &lt;span class=&quot;inlineCode&quot;&gt;structs&lt;/span&gt; in general, &lt;span class=&quot;inlineCode&quot;&gt;Delegates&lt;/span&gt;, lists and dictionaries.&lt;/p&gt;

&lt;p&gt;JavaScript dates are ordinary objects. This is why we treat them as such by marshaling them to &lt;span class=&quot;inlineCode&quot;&gt;ScriptObjects&lt;/span&gt;, just like we do with any other type of 
JavaScript object. The only difference is that we check what type of value the target site expects. If it expects a &lt;span class=&quot;inlineCode&quot;&gt;DateTime&lt;/span&gt;, we will convert it to that. 
Similarly, when you pass a &lt;span class=&quot;inlineCode&quot;&gt;DateTime&lt;/span&gt; to JavaScript, we will convert it to a real JavaScript date object.&lt;/p&gt;

&lt;p&gt;Our support for &lt;span class=&quot;inlineCode&quot;&gt;Guids&lt;/span&gt; is trivial. When one is passed to JavaScript, the marshalling layer converts it to a &lt;span class=&quot;inlineCode&quot;&gt;string&lt;/span&gt;. We 
do this because it's fairly common to use &lt;span class=&quot;inlineCode&quot;&gt;Guids&lt;/span&gt; as identifiers for data, and the easiest way to represent them in JavaScript is via an ordinary 
&lt;span class=&quot;inlineCode&quot;&gt;string&lt;/span&gt;. If you round-trip such a string back to managed code, we will only attempt to convert it back to a &lt;span class=&quot;inlineCode&quot;&gt;Guid&lt;/span&gt; if the target 
site expects a value of this type.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;inlineCode&quot;&gt;Struct&lt;/span&gt; support is relatively basic too. We try to enforce the right semantics by making sure we create copies of values before marshalling them, which involves 
boxing the value. Without explicitly copying the values, there are cases where a value type would very much act like a reference type. For example, passing a value type to JavaScript where one of 
the fields gets mutated would in fact mutate the field on the value on the caller's site.&lt;/p&gt;

&lt;p&gt;Anything else that is not a &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt; or primitive will be marshaled by reference as a managed object. To understand how managed objects are marshaled, we 
should first take a look at how browser objects are marshaled.&lt;/p&gt;

&lt;h3&gt;Browser object marshalling&lt;/h3&gt;

&lt;p&gt;All browser objects are represented by &lt;span class=&quot;inlineCode&quot;&gt;ScriptObjects&lt;/span&gt;. This includes ordinary JavaScript objects, but also windows (&lt;span class=&quot;inlineCode&quot;&gt;HtmlWindow&lt;/span&gt;), 
documents (&lt;span class=&quot;inlineCode&quot;&gt;HtmlDocument&lt;/span&gt;) elements (&lt;span class=&quot;inlineCode&quot;&gt;HtmlElement&lt;/span&gt;), element collections (&lt;span class=&quot;inlineCode&quot;&gt;HtmlElementCollection&lt;/span&gt;) and 
even managed objects (&lt;span class=&quot;inlineCode&quot;&gt;ManagedObject&lt;/span&gt;, an internal type) that have gotten a life inside the browser. We do a lot of things when the browser returns an object reference 
to us as after invoking a function or property. This is all done transparently, so you don't need to worry about any of this, but it gives you an idea of what's really happening in part of the 
marshalling layer.&lt;/p&gt;

&lt;h4&gt;Type inference&lt;/h4&gt;

&lt;p&gt;In Silverlight 1.1 alpha we forced you to tell us what the type of an object was going to be via a generic type parameter. While the glorified cast may seem nicer than the casts you need now, 
you would quickly find that you don't always know the type of an object. In one place you may assume the elements of an array are of type &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt;, while in 
reality one of the elements is in fact an HTML DOM element. This made it difficult for us to guarantee correctness, impacting the reliability of any code that used our bridge.&lt;/p&gt;

&lt;p&gt;This has changed in Silverlight 2. We now automatically determine the type of an object. In Internet Explorer we can do this very efficiently through a few native calls to 
&lt;span class=&quot;inlineCode&quot;&gt;QueryInterface&lt;/span&gt;. In the other browsers we are forced to determine the type via some 'JavaScript reflection.' In both Firefox and Safari this boils down to inspecting 
&lt;span class=&quot;inlineCode&quot;&gt;nodeType&lt;/span&gt; to see if an object is a document or element. If the object doesn't have this property, we will check if the object is an instance of 
&lt;span class=&quot;inlineCode&quot;&gt;HTMLWindow&lt;/span&gt;, &lt;span class=&quot;inlineCode&quot;&gt;NodeList&lt;/span&gt; or &lt;span class=&quot;inlineCode&quot;&gt;HTMLCollection&lt;/span&gt; in Firefox. In Safari 2 we'll look at a few other properties 
that let us determine whether it's a window or element collection.&lt;/p&gt;

&lt;p&gt;We only need to do this when the value that the browser returned to us is an object. For every value the browser returns to us, it lets us know whether it's a &lt;span class=&quot;inlineCode&quot;&gt;bool&lt;/span&gt;, 
&lt;span class=&quot;inlineCode&quot;&gt;int&lt;/span&gt;, &lt;span class=&quot;inlineCode&quot;&gt;double&lt;/span&gt;, or an &lt;span class=&quot;inlineCode&quot;&gt;object&lt;/span&gt;, so we don't always need to do additional work to find out the type of a 
return value.&lt;/p&gt;

&lt;h4&gt;Object identity&lt;/h4&gt;

&lt;p&gt;When the browser returns a value, we convert or marshal this to a managed value. For primitives this is a straightforward process. Objects however are simply a pointer, so we need to marshal it 
to something that is usable from managed code. We need to marshal it to a &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt; or one of its derivates, based on the type we previously inferred.&lt;/p&gt;

&lt;p&gt;The simplest thing we could've done is marshal a pointer to a new object every time. This would have several consequences though. In scenarios involving lots of round-tripping of objects, memory 
usage would grow and the pressure on the GC would increase. More importantly, we would have a correctness problem. Imagine the following code:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; f1 = HtmlPage.Document.GetElementById(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;foo&lt;/span&gt;&amp;quot;);
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; f2 = Htmlpage.Document.GetElementById(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;foo&lt;/span&gt;&amp;quot;);
assert(f1.Id == f2.Id); &lt;span style=&quot;color:#008000&quot;&gt;// True.&lt;/span&gt;
assert(f1 == f2); &lt;span style=&quot;color:#008000&quot;&gt;// False.&lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;This code queries for the same element twice. The variables &lt;span class=&quot;inlineCode&quot;&gt;f1&lt;/span&gt; and &lt;span class=&quot;inlineCode&quot;&gt;f2&lt;/span&gt; both refer to a different managed object, which in turn both wrap the same native browser object. This object identity issue 
might seem unimportant, but it hits you whenever you need to tell whether two objects are the same.&lt;/p&gt;

&lt;p&gt;We could deal with this by overriding &lt;span class=&quot;inlineCode&quot;&gt;Equals/op_Equals&lt;/span&gt; and letting it compare the underlying browser object pointers, and let &lt;span class=&quot;inlineCode&quot;&gt;GetHashCode&lt;/span&gt; 
return the pointer's hash code. Although this would probably address the majority of the situations, it would simply be a work around. There still wouldn't be true object identity. You would still get 
the wrong result when comparing two variables typed as &lt;span class=&quot;inlineCode&quot;&gt;Object&lt;/span&gt;, as the CLR would end up comparing the references, rather than calling into the overloaded equals operator. 
Furthermore the &lt;span class=&quot;inlineCode&quot;&gt;GetHashCode&lt;/span&gt; implementation would be rather inefficient on Safari – which I'll explain further in a second.&lt;/p&gt;

&lt;p&gt;To correctly implement object identity, we need to know whether we already marshaled a browser object before. If we did, we simply return that object. Otherwise, we marshal it and make sure we keep 
track of the managed object we create. We introduced an object cache in &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt; for exactly this.&lt;/p&gt;

&lt;p&gt;The object cache maps pointers to &lt;span class=&quot;inlineCode&quot;&gt;WeakReferences&lt;/span&gt; of &lt;span class=&quot;inlineCode&quot;&gt;ScriptObjects&lt;/span&gt;. By using weak references we avoid keeping alive objects forever. 
Additionally, &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt; implements a finalizer to remove its entry in the object cache, such that we're not leaking at least &lt;span class=&quot;inlineCode&quot;&gt;sizeof(IntPtr)&lt;/span&gt; 
bytes per object that no longer exists.&lt;/p&gt;

&lt;p&gt;At this point there's only one remaining problem. Safari doesn't preserve object identity in its plugin API, which means that we get back different pointers every time for the same native browser 
object. It is important to note that the pointers we get back are pointers to objects which wrap the real browser object – even so in FF. Both browsers support the NPAPI, a plugin API supported by most 
browsers, which defines the contract of an object (&lt;span class=&quot;inlineCode&quot;&gt;NPObject&lt;/span&gt;). To adhere to this contract, it usually needs to marshal its browser objects itself. Firefox seemingly does 
this by caching &lt;span class=&quot;inlineCode&quot;&gt;NPObjects&lt;/span&gt; to preserve object identity and reduce memory overhead. Safari apparently creates a new &lt;span class=&quot;inlineCode&quot;&gt;NPObject&lt;/span&gt; every time.&lt;/p&gt;

&lt;p&gt;We addressed this problem by introducing a second object cache, which maps a custom identifier (an &lt;span class=&quot;inlineCode&quot;&gt;int&lt;/span&gt;) to an &lt;span class=&quot;inlineCode&quot;&gt;IntPtr&lt;/span&gt; of the browser object 
that we marshaled before, which is also the key in the primary object cache. We generate custom identifiers ourselves, and try to store this in a private field (&lt;span class=&quot;inlineCode&quot;&gt;$__slid&lt;/span&gt;) on 
the object, such that we can read this back later when we need to marshal another pointer. Whenever we are trying to marshal a pointer, we first try to read this private field and do a lookup in our secondary 
object cache to get back a different pointer (to this object) which we marshaled before.&lt;/p&gt;

&lt;p&gt;This secondary cache is purely used as a heuristic to improve performance. We don't rely on any of the information we gather in this process. We use it to do a lookup in the real object cache, and we then 
call into script to verify the two pointers we have (a pointer which we want to marshal, and a pointer we marshaled before and believe points to the same browser object) do indeed point to the same browser 
object. We do this by calling into an anonymous JavaScript helper function, which looks like:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;JavaScript:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;function&lt;/span&gt;(obj1, obj2) {
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; (obj1 == obj2);
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;When we pass two pointers to native browser objects, &lt;span class=&quot;inlineCode&quot;&gt;NPObjects&lt;/span&gt;, the browser will marshal these back to real browser objects. In every browser, including Safari, it will get 
back the original browser objects. Because of this, we can correctly tell whether two objects are the same in JavaScript.&lt;/p&gt;

&lt;p&gt;Back in managed code we can use this to verify that two pointers are indeed the same. If they are, we go ahead and return the managed object we created before for this object. If they aren't, we will 
walk through our primary object cache and check if this pointer really wasn't marshaled before, by comparing each pointer to the current pointer via a call to our JavaScript helper function. If it turns out 
we never marshaled this browser object before, we will generate a new identifier and associate try to associate it with this browser object. We will update both object caches accordingly.&lt;/p&gt;

&lt;p&gt;This process does involve a slight performance hit on Safari, in particular when you often marshal objects that you never marshaled before. Unfortunately there's not much we can do about this given the 
way Safari decided to implement the NPAPI, without sacrificing the usability of our managed API.&lt;/p&gt;

&lt;h3&gt;Managed object marshalling&lt;/h3&gt;

&lt;p&gt;Marshalling to JavaScript objects involves creating a browser object which wraps the managed object and acts as a proxy. Internally it's a &lt;span class=&quot;inlineCode&quot;&gt;ManagedObject&lt;/span&gt; which derives from 
&lt;span class=&quot;inlineCode&quot;&gt;Scriptobject&lt;/span&gt;. When a managed object is round-tripped, we will return its &lt;span class=&quot;inlineCode&quot;&gt;ManagedObject&lt;/span&gt;, rather than the real managed object it wraps. You can 
access the underlying managed object via the &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject.ManagedObject&lt;/span&gt; property.&lt;/p&gt;

&lt;p&gt;We decided to return &lt;span class=&quot;inlineCode&quot;&gt;ManagedObjects&lt;/span&gt; rather than their underlying objects to make the programming model more consistent and increase the reliability of user code: every object 
can be treated in the same way, just like you can in JavaScript. This means you don't have to constantly check if an object is either a browser object or a managed object.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;inlineCode&quot;&gt;ManagedObjects&lt;/span&gt; reference a &lt;span class=&quot;inlineCode&quot;&gt;ManagedObjectInfo&lt;/span&gt; which stores a method table with entries for each scriptable member for that type. The entries 
are wrappers around the actual members, which makes it possible for us to add special-casing for certain type of members, such as properties and events.&lt;/p&gt;

&lt;p&gt;For every managed type we lazily construct the (case-sensitive) method table and cache this information for performance reasons. We use weak references such that this information can be released when there's 
no reason to hold onto it any longer. The process for constructing the method table for most types involves walking through all public members with a &lt;span class=&quot;inlineCode&quot;&gt;ScriptableMemberAttribute&lt;/span&gt;. 
We then walk their inheritance tree. For every type in this tree with a &lt;span class=&quot;inlineCode&quot;&gt;ScriptableTypeAttribute&lt;/span&gt; we add all of that type's declared members. This means that if you apply this 
attribute to your type, it will only add the members you declared in your type; it does not include any inherited members. We also add an &lt;span class=&quot;inlineCode&quot;&gt;addEventListener&lt;/span&gt; and 
&lt;span class=&quot;inlineCode&quot;&gt;removeEventListener&lt;/span&gt; method to the method table to support events in the same kind of way they're supported in the HTML DOM.&lt;/p&gt;

&lt;p&gt;Another method we add is &lt;span class=&quot;inlineCode&quot;&gt;createManagedObject&lt;/span&gt;. This method lets you create instances of complex types that are used as parameters for any of the scriptable members. For example, 
if you have a &lt;span class=&quot;inlineCode&quot;&gt;CustomerService&lt;/span&gt; type with a scriptable &lt;span class=&quot;inlineCode&quot;&gt;Add(Customer)&lt;/span&gt; method, you will be able to create an instance of such a 
&lt;span class=&quot;inlineCode&quot;&gt;Customer&lt;/span&gt; type, assuming it has a public default constructor:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; customerService = plugin.content.customerService;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; customer = customerService.createManagedObject(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Customer&lt;/span&gt;&amp;quot;);
customer.Name = &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;John Doe&lt;/span&gt;&amp;quot;; &lt;span style=&quot;color:#008000&quot;&gt;// Assume we marked Customer.Name as a scriptable member.&lt;/span&gt;
customerService.Add(customer);

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;By automatically doing this work for you, you don't need to add calls to &lt;span class=&quot;inlineCode&quot;&gt;HtmlPage.RegisterCreatableType&lt;/span&gt; all over the place. You also don't need to hold on to the plugin object 
in order to call &lt;span class=&quot;inlineCode&quot;&gt;createObject&lt;/span&gt; to instantiate a type registered via &lt;span class=&quot;inlineCode&quot;&gt;RegisterCreatableType&lt;/span&gt;. In other words, each object that is a receiver (i.e. has 
a scriptable method which takes a complex object) is also a factory which creates complex objects.&lt;/p&gt;

&lt;p&gt;We have basic support for method overloading, by finding the overload which matches the number of arguments and by doing some basic parameter validation.&lt;/p&gt;

&lt;p&gt;&lt;span class=&quot;inlineCode&quot;&gt;Delegates&lt;/span&gt; are a special-case scenario. We map a delegate's &lt;span class=&quot;inlineCode&quot;&gt;DynamicInvoke&lt;/span&gt; method and add an &lt;span class=&quot;inlineCode&quot;&gt;apply&lt;/span&gt; method. This 
method allows you to invoke delegates in a 'late-bound' fashion from JavaScript. We will take care of unrolling the array of arguments and call &lt;span class=&quot;inlineCode&quot;&gt;DynamicInvoke&lt;/span&gt; on the delegate.&lt;/p&gt;

&lt;p&gt;JavaScript functions are automatically marshaled to delegates if the target site expects one. Silverlight 2 currently only supports delegates that are compatible with the 
&lt;span class=&quot;inlineCode&quot;&gt;void(object, EventArgs)&lt;/span&gt; signature, such as &lt;span class=&quot;inlineCode&quot;&gt;EventHandler&lt;/span&gt; and &lt;span class=&quot;inlineCode&quot;&gt;EventHandler&amp;lt;TEventArgs&amp;gt;&lt;/span&gt;. Arbitrary delegate
types aren't supported – at least not at the time of writing.&lt;/p&gt;

&lt;p&gt;Types that implement &lt;span class=&quot;inlineCode&quot;&gt;IList&lt;/span&gt; will end up storing members in the method table that correspond to the functions that JavaScript arrays support. This means managed arrays, 
&lt;span class=&quot;inlineCode&quot;&gt;List&amp;lt;T&amp;gt;s&lt;/span&gt;, and so on can be treated and used as arrays in JavaScript.&lt;/p&gt;

&lt;p&gt;Similarly, types with support for &lt;span class=&quot;inlineCode&quot;&gt;IDictionary&amp;lt;string, TValue&amp;gt;&lt;/span&gt; are also made more accessible from JavaScript. The keys in such a dictionary translate to fields in 
JavaScript. When you set a field, we will add or set the value with the field's name as the key. Accessing a field translates to a lookup in the dictionary.&lt;/p&gt;

&lt;p&gt;Lastly, we always map the &lt;span class=&quot;inlineCode&quot;&gt;ToString&lt;/span&gt; method of every type, because some browsers implicitly call &lt;span class=&quot;inlineCode&quot;&gt;toString&lt;/span&gt; on objects, for example when passing 
them to &lt;span class=&quot;inlineCode&quot;&gt;alert&lt;/span&gt;.&lt;/p&gt;

&lt;h3&gt;Object lifetime&lt;/h3&gt;

&lt;p&gt;Normally a managed object gets collected by the GC when it's no longer rooted. In other words, when an object can no longer be accessed, the GC is allowed to collect it. When we pass such an object to the 
browser, we have to prevent this behavior. We do this by pinning the &lt;span class=&quot;inlineCode&quot;&gt;ManagedObject&lt;/span&gt; and giving lifetime ownership to the browser object that wraps it. This browser object is always 
a reference counted object which will unpin the &lt;span class=&quot;inlineCode&quot;&gt;ManagedObject&lt;/span&gt; when the last reference is released.&lt;/p&gt;

&lt;p&gt;We will re-create the native browser object on the fly when a &lt;span class=&quot;inlineCode&quot;&gt;ManagedObject&lt;/span&gt; is passed to the browser after its native counter-part no longer exists.&lt;/p&gt;

&lt;p&gt;If the managed runtime shuts down when the browser still has a reference to a managed object, for example by removing the plugin from the DOM after getting the reference, the browser object wrapping the 
managed object will know about this and gracefully let all calls fail. When the last reference goes away, it won't attempt to unpin the managed object either, which isn't a problem as the managed object was 
already freed from memory during the managed runtime shutdown.&lt;/p&gt;

&lt;p&gt;The lifetime of all other objects is more trivial. Either when the managed runtime shuts down, or when a &lt;span class=&quot;inlineCode&quot;&gt;ScriptObject&lt;/span&gt; gets GC'ed because it's no longer reachable, we will 
release our reference to the native object. We guarantee that this reference is released on the UI thread.&lt;/p&gt;

&lt;h3&gt;Exception handling&lt;/h3&gt;

&lt;p&gt;Silverlight returns exceptions thrown in managed code as JavaScript errors. It does this by calling &lt;span class=&quot;inlineCode&quot;&gt;ToString&lt;/span&gt; on the exceptions, and then it passes this exception text on to 
the caller. Internet Explorer stores this in an error object. When catching this error, you can get back the exception text by accessing the &lt;span class=&quot;inlineCode&quot;&gt;message&lt;/span&gt; field. In all other browsers 
the object that you catch is the exception text.&lt;/p&gt;

&lt;p&gt;There's one exception. It appears that Safari ignores any reported errors. This means that if you invoke a method which throws, your JavaScript code won't know if anything went wrong. It'll simply not get back 
a value. One way to deal with this is by always returning something from managed code, such as a &lt;span class=&quot;inlineCode&quot;&gt;Boolean&lt;/span&gt; value. This way you can assume something went wrong when you don't get back 
any value.&lt;/p&gt;

&lt;p&gt;The opposite – throwing exceptions in JavaScript back to managed code – works similarly. Unfortunately the plugin API we use for browsers other than Internet Explorer (NPAPI) doesn't have first-class support 
for reporting exceptions. We can only tell whether a call failed or succeeded. We considered invoking JavaScript functions via a helper function, but this requires the ability to invoke JavaScript functions in a 
late-bound way (via &lt;span class=&quot;inlineCode&quot;&gt;Function.apply&lt;/span&gt;), something that isn't supported by every version of Safari that we support. Consequently we simply throw a generic 
&lt;span class=&quot;inlineCode&quot;&gt;InvalidOperationException&lt;/span&gt; whenever a JavaScript function invocation fails. In Internet Explorer it contains the error text of the exception that was thrown, while in all other 
browsers you will simply see a generic error message.&lt;/p&gt;

&lt;h2&gt;Use case: Extending the browser with OpenFileDialog support&lt;/h2&gt;

&lt;p&gt;Most browsers today don't support reading files on the client. You have to use an &lt;span class=&quot;inlineCode&quot;&gt;input&lt;/span&gt; element of type 'file' and let the browser send the file to the server, which can then 
echo the contents back to the client. Besides the somewhat awkward user experience, it also complicates the programming model. You have to restore the state of the page, or you have to use an iframe and do the 
round-tripping there.&lt;/p&gt;

&lt;p&gt;Silverlight comes with an OpenFileDialog feature. This dialog provides read-only streams to one or more files selected by the user. Out of the box you can only use this feature from managed code. It takes 
little effort to encapsulate this feature though. Let's take a look at what it takes to extend the browser with this feature.&lt;/p&gt;

&lt;h3&gt;Step 1: Adding a Silverlight island to the page&lt;/h3&gt;

&lt;p&gt;There are several ways to do this. The easiest is to use VS and let it generate a page with Silverlight for you. It will embed Silverlight via an object tag, which refers to your Silverlight application (a 
.xap file). To integrate this application with your website, all you need to do is copy this object tag declaration and the .xap file.&lt;/p&gt;

&lt;p&gt;Since our feature doesn't have any UI on the page, you can make sure the object tag's width and height is 0 pixels. You shouldn't use the &lt;span class=&quot;inlineCode&quot;&gt;display&lt;/span&gt; or 
&lt;span class=&quot;inlineCode&quot;&gt;visibility&lt;/span&gt; styles to make Silverlight invisible, as Silverlight may not even run at all in that case.&lt;/p&gt;

&lt;h3&gt;Step 2: Making OpenFileDialog scriptable&lt;/h3&gt;

&lt;p&gt;We can make &lt;span class=&quot;inlineCode&quot;&gt;OpenFileDialog&lt;/span&gt; scriptable by introducing a few wrappers. For the &lt;span class=&quot;inlineCode&quot;&gt;OpenFileDialog&lt;/span&gt; type itself we can simply add a scriptable method to 
our application. We'll let this method return an array of scriptable objects which wrap the &lt;span class=&quot;inlineCode&quot;&gt;OpenFileDialog's&lt;/span&gt; &lt;span class=&quot;inlineCode&quot;&gt;SelectedFiles&lt;/span&gt; property. In code this 
looks like:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;12 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;13 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;14 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;class&lt;/span&gt; App : Application {

&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; ScriptableFileInfo OpenFiles(&lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; filter) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; dialog = &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; OpenFileDialog();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dialog.Filter = filter;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;if&lt;/span&gt; (dialog.ShowDialog() == DialogResult.OK) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; fileInfos = &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; ScriptableFileInfo[dialog.SelectedFiles.Length];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color:#0000FF&quot;&gt;int&lt;/span&gt; i = 0; i &amp;amp;lt; dialog.SelectedFiles.Length; i++) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fileInfos[i] = &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; ScriptableFileInfo(fileInfos[i]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; ScriptableFileInfo[0];
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;And the &lt;span class=&quot;inlineCode&quot;&gt;ScriptableFileInfo&lt;/span&gt; type can be implemented like this:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;5 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;6 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;7 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;8 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;9 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;10 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;11 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;12 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;13 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;14 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;15 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;16 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;17 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;18 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;19 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;20 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;21 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;22 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;23 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;24 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;class&lt;/span&gt; ScriptableFileInfo {

&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;private&lt;/span&gt; FileDialogFileInfo _info;

&amp;nbsp;&amp;nbsp;&amp;nbsp; [ScriptableMember(ScriptAlias = &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;contents&lt;/span&gt;&amp;quot;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; Contents {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; reader = &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; StreamReader(_info.OpenRead()) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; reader.ReadToEnd();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; [ScriptableMember(ScriptAlias = &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;fileName&lt;/span&gt;&amp;quot;)]
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt; FileName {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;get&lt;/span&gt; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;return&lt;/span&gt; _info.FileName;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }

&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;public&lt;/span&gt; ScriptableFileInfo(FileDialogFileInfo info) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _info = info;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;Now, we still need to expose this to script. There are two options we can choose from:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Add a &lt;span class=&quot;inlineCode&quot;&gt;ScriptableMemberAttribute&lt;/span&gt; to our &lt;span class=&quot;inlineCode&quot;&gt;OpenFiles&lt;/span&gt; method, and register our application
  object as a scriptable object by calling &lt;span class=&quot;inlineCode&quot;&gt;HtmlPage.RegisterScriptableObject&lt;/span&gt;.&lt;/li&gt;
  &lt;li&gt;Encapsulate our &lt;span class=&quot;inlineCode&quot;&gt;OpenFiles&lt;/span&gt; method via a delegate which is
  accessible from script.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We will go with the last option because it's the easiest to work with from JavaScript. It's also just as easy to implement. In our application's constructor we simply add:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;C#:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
HtmlPage.Window.SetProperty(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;openFiles&lt;/span&gt;&amp;quot;, &lt;span style=&quot;color:#0000FF&quot;&gt;new&lt;/span&gt; Func&amp;lt;&lt;span style=&quot;color:#0000FF&quot;&gt;string&lt;/span&gt;, ScriptableFileInfo[]&amp;gt;(OpenFiles));

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;h3&gt;Step 3: Using OpenFileDialog from JavaScript&lt;/h3&gt;

&lt;p&gt;Now that we've added an &lt;span class=&quot;inlineCode&quot;&gt;openFiles&lt;/span&gt; function to the &lt;span class=&quot;inlineCode&quot;&gt;window&lt;/span&gt; object, we can access it from JavaScript like this:&lt;/p&gt;


						&lt;table style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
								&lt;td colspan=&quot;2&quot; style=&quot;width: 100%&quot;&gt;
									&lt;b&gt;JavaScript:&lt;/b&gt;
								&lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;
						&lt;table class=&quot;code&quot; style=&quot;width: 100%&quot;&gt;
							&lt;tr&gt;
							        &lt;td style=&quot;width: 1%; text-align: right; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span class=&quot;shl_ln&quot;&gt;1 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;2 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;3 &lt;/span&gt;
&lt;span class=&quot;shl_ln&quot;&gt;4 &lt;/span&gt;

&lt;/pre&gt;
							        &lt;/td&gt;
							        &lt;td style=&quot;width: 99%; vertical-align: top&quot;&gt;
&lt;pre&gt;
&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; selectedFiles = &lt;span style=&quot;color:#0000FF&quot;&gt;window&lt;/span&gt;.openFiles(&amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;Text Files|*.txt;*.csv|All Files|*.*&lt;/span&gt;&amp;quot;);
&lt;span style=&quot;color:#0000FF&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color:#0000FF&quot;&gt;var&lt;/span&gt; i = 0; i &amp;lt; selectedFiles.&lt;span style=&quot;color:#0000FF&quot;&gt;length&lt;/span&gt;; i++) {
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;color:#0000FF&quot;&gt;alert&lt;/span&gt;(selectedFiles[i].fileName + &amp;quot;&lt;span style=&quot;color:#8B0000&quot;&gt;: &lt;/span&gt;&amp;quot; + selectedFiles[i].contents);
}

&lt;/pre&gt;
							        &lt;/td&gt;
							&lt;/tr&gt;
						&lt;/table&gt;

&lt;p&gt;We do still need to be careful about when we execute this code. The &lt;span class=&quot;inlineCode&quot;&gt;openFiles&lt;/span&gt; function won't be there until our application has been downloaded and its constructor 
has executed. You can account for this by handling the &lt;span class=&quot;inlineCode&quot;&gt;onload&lt;/span&gt; event on the Silverlight plugin. Once this event has occurred, you should be able to safely use the 
&lt;span class=&quot;inlineCode&quot;&gt;openFiles&lt;/span&gt; function on the &lt;span class=&quot;inlineCode&quot;&gt;window&lt;/span&gt; object.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;
Silverlight does a lot of work under the hood to make it a first-class citizen in the browser. People writing managed code can fully integrate with the existing codebase for a website. Those who prefer to continue writing JavaScript can fully leverage the features offered by Silverlight with little effort. This should allow everyone to get at least something out of Silverlight.
&lt;/p&gt;
&lt;/div&gt;</description>
</item>
<item>
<title>Rendering viewst