Silverlight Playground
about Silverlight and other Amenities

FormsAuthentication and ClientHttpStack with mixed applications

2010-08-30T16:41:47+01:00 by Andrea Boschin

If you ever tried to have mixed applications, with some regular ASP.NET pages and a bunch of Silverlight applications, where the forms authentication is made with a traditional ASP.NET login page, you have for sure found that you are forced to use the BrowserHttp stack into the Silverlight applications because the FormsAuthentication cookie is not shared between the ASP.NET page and the new ClientHttp stack that is available since Silverlight 3.0.

Since the new ClientHttp stack for many reasons is a huge improvement, is would be a beautiful thing being able to use this stack every time there is the need to place HTTP calls. Finally I found a way to share this cookie across the two stacks, but I want to warn you that the sole way to accomplish this task require a little "dirty hack", that someone might consider unacceptable while it opens some minor security concerns I will detail at the end of the post.

Before continue reading this post please have in mind that my suggestion is to always use the BrowserHttp stack in these scenario, until you do not really need the new stack, e.g. if you have to use some special verb or for some other particular reason.

The dirty hack explained

The first thing you have to know is that when you are using the ClientHttp stack you are free to access the cookies issued by the server and it is also possible to add some cookies to attach to a call. The task we would have to accomplish is simply to read a cookie (often called .ASPXAUTH) from the BrowserHttp stack and add it to the ClientHttp stack and it may seems and easy task.

Unfortunately the BrowserHttp Stack prevent us from accessing the cookies. The cookies management is one of the features that has been added by the new ClientHttp stack and there is not any way to pump out them from the old one.

So my first try was to use the HtmlPage.Document.Cookies property, as I found in some examples on the Internet. Perhaps this may work when the authentication cookie is issued by a custom authentication system, but with FormsAuthentication it is another failed try because the cookies issued by the ASP.NET engine are HttpOnly. This attribute, added since IE6 SP1, prevents the browser scripts - and Silverlight is considered a client script - from accessing these cookies that remain hidden.

So, how can we share these cookies? The only thing you can do is to add the cookie to the InitParams collection when you initialize the plugin in the html page. You have to change this page to be an aspx page and then you can create two keys into the InitParams collection like the following:

   1: public string GetFormsAuthenticationCookie()
   2: {
   3:     return string.Format(
   4:         "FormsCookieName={0},FormsCookieValue={1}",
   5:         FormsAuthentication.FormsCookieName,
   6:         this.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
   7: }

Then in the plugin I would like to have a centralized class reponsible of creating the cookie and adding it to each server call I do. First of all, if you are using WCF you have to enable the CookieContainer from the ServiceReferences.ClientConfig file. You have to add an attribute that exists only in the Siverlight side of the configuration:

   1: <basicHttpBinding>
   2:     <binding name="BasicHttpBinding_IWCFService" 
   3:               maxBufferSize="2147483647"
   4:               enableHttpCookieContainer="True"
   5:               maxReceivedMessageSize="2147483647">
   6:         <security mode="None" />
   7:     </binding>
   8: </basicHttpBinding>

The enableCookieContainer attribute initializes an instance of an IHttpCookieContainerManager into the WCF client an this allow us to manage cookies using the CookieContainer collection. Now we can write a simple application service to put into the app.xaml that we can use to instantiate and initialize the client. The reason of creating an application service is to have a common place where initialize a shared cookie container that reads the InitParam and add the received cookies into it:

   1: public class ClientCreatorService : IApplicationService
   2: {
   3:     public static ClientCreatorService Current
   4:     {
   5:         get
   6:         {
   7:             return Application.Current.ApplicationLifetimeObjects.OfType<ClientCreatorService>().Single();
   8:         }
   9:     }
  10:  
  11:     private CookieContainer SharedCookies { get; set; }
  12:  
  13:     public void StartService(ApplicationServiceContext context)
  14:     {
  15:         this.SharedCookies = new CookieContainer();
  16:         string formsCookieName = context.ApplicationInitParams["FormsCookieName"];
  17:         string formsCookieValue = context.ApplicationInitParams["FormsCookieValue"];
  18:         this.SharedCookies.Add(new Uri(Application.Current.Host.Source, "../"), new Cookie(formsCookieName, formsCookieValue));
  19:     }
  20:  
  21:     public K CreateClient<T, K>()
  22:         where K : ClientBase<T>, new()
  23:         where T : class
  24:     {
  25:         K client = new K();
  26:         IHttpCookieContainerManager cookieManager = client.InnerChannel.GetProperty<IHttpCookieContainerManager>();
  27:         cookieManager.CookieContainer = this.SharedCookies;
  28:         return client;
  29:     }
  30:  
  31:     public void StopService()
  32:     {}
  33: }

During the initialization the ClientCreatorService initialize the SharedCookies with the FormsCookieName and FormsCookieValue. Then the generic CreateClient methid is able to instantiate the required client and add the SharedCookies to it. The usage of the Application Service is pretty simple. Here is how to instantiate the client and place a call:

   1: WCFServiceClient client = ClientCreatorService.Current.CreateClient<IWCFService, WCFServiceClient>();
   2: client.GetIdentityCompleted += new EventHandler<GetIdentityCompletedEventArgs>(client_GetIdentityCompleted);
   3: client.GetIdentityAsync();

If you try the code you will find that the GetIdentity method is able to retrive the membership identity from the HttpContext.Current.User property. This means your service runs in an authenticated context.

What is the drawback?

When you make a dirty thing you have to be aware that there is always almost a drawback. In this case the problem is that the injection of the authentication cookie in the InitParams opens a subtle security concern that is mitigated by the fact that the informations we are disclosing are already public even before my trick was up and running. The use of HttpOnly cookies for authentication is an important improvement that prevent the use of XSS attacks. Having the cookie injected in the page, re-open the window to some pre-IE6 SP1 scripts that could try to access the InitParams collection from javascript and simulate the authentication to the system like our Silverlight application actually does.

This problem must be always in your mind and you have to put on the scale both the advantage of having the ClientHttp working and the security concerns of this trick. My hope is that the Silverlight team will be able to solve this issue in next releases of the plugin, so we can rely on a secure implementation and avoid dirty tricks.

Categories:   Networking | TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Review: Microsoft Silverlight 4 Data and Services Cookbook

2010-08-19T22:48:02+01:00 by Andrea Boschin

Microsoft_Silverlight_4_Data_and_Services_Cookbook Some time ago I've received a copy of the book "" and finally I was able to read it during my recent holidays. So I decided to write this brief review to suggest you to give it a chance, because I found this book is really interesting for someone need to start learning Silverlight 4.0.

The book is a sort of collection of recipes, that describes some use cases of Silverlight applications that give a good framing for various aspect of this technology. 

The ten chapters cover all the basic arguments someone may need to start writing applications, from the first project and the use of Blend, to more advanced topics like databinding, the data controls and the usage of WCF Service and Ria services.

I think the people usually ask me about good books to start from, may found this cookbook useful for this purpose.

Tags:   ,
Categories:   Review
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Demo from Italy Remix 2010

2010-07-01T22:44:49+01:00 by Andrea Boschin

Last June 23 I had the pleasure of presenting an introductive session about Silverlight at . During the presentation, included in the “jump start” track, I’ve illustrated the basic capabilities of Silverlight using a simple application that consume a RSS feed from the . The feed give news about all the Earthquakes happening on the world surface and all them are geo tagged.

So, during the session, I’ve showed the application growing from a simple reader to a complex and effective tool to display the earthquakes on a map, using the Silverlight control for Bing Maps. The people was impressed by the application, so I decided to publish the sample on my blog, hoping it can become a good starting point for people wants to approach the Silverlight development.

The application is really simple, without any surprise for skilled people, but it show the main points, from where someone must start. You can see layout, shapes, brushes, animations, projections, network access, syndication and data binding, but also show the power of an Out of browser application and the customization of the window chrome. I hope you enjoy the sample.

Download: code | live demo

Keeping an ObservableCollection sorted with a method override

2010-04-27T16:30:52+01:00 by Andrea Boschin

Usually the order of elements in a collection is something one does not feel to be important. We have plenty of methods in the Framework to order things and now that there is LINQ to Objects the need to sort something is really matter of seconds.

Since the introduction of LINQ the main problem is that you have many cases where a few lines of code are adding really complex iteration logic and often this hurts performances when the count of milliseconds is something important.

In these days I had this problem because I did need to make a lot of updates to a collection in the short time as possible, because I was working into the a CompositionTarget_Rendering event. A lot of hidden iterations through the collection, made by LINQ queries, has degraded the performances of the application and I had to put my nose on the iteration logic to optimize it.

In a case like this, having a collection that ensure a given order of the elements was key to solve my problem. So I decided to implement a SortedObservableCollection that helped me to minimize scans of the collection. Here is the simple code:

   1: public class SortedObservableCollection<T> : ObservableCollection<T>
   2:     where T : IComparable
   3: {
   4:     protected override void InsertItem(int index, T item)
   5:     {
   6:         for (int i = 0; i < this.Count; i++)
   7:         {
   8:             switch (Math.Sign(this[i].CompareTo(item)))
   9:             {
  10:                 case 0:
  11:                     throw new InvalidOperationException("Cannot insert duplicated items");
  12:                 case 1:
  13:                     base.InsertItem(i, item);
  14:                     return;
  15:                 case -1:
  16:                     break;
  17:             }
  18:         }
  19:  
  20:         base.InsertItem(this.Count, item);
  21:     }
  22: }

The trick has been done in a few minutes, just because the ObservableCollection exposes some overridable methods that enable the developer to change the Insert and Remove behavior. So I simply overriden the InsertItem method. I changed it trying to put elements in the right place, evaluating the position over the elements already in the collection. This helped me to move the sorting logic in another context, out of the Rendering event, and maximize the performances.

The code I wrote in this sample is really simple. I figure out you can improve again the performances of the InsertItem method implementing a binary search algorithm. But it is a little concern when you know where to act.

Using a PollingDuplex service to handle long running activities

2010-04-24T23:30:13+01:00 by Andrea Boschin

In a previous post I proposed an example about using a Polling Duplex service to notify a number of client about events happening to a common resource. In that complex example I did show a service that runs a thread that monitors the resource. Every time the resource is changed the thread detects the change and notifies a list of connected clients to display a sort of bus station timetable. This kind of service handles only one of the possible problems you can solve using the PollingDuplex.

Imagine you have a long task to accomplish and need to get updates from the webserver that is running the activity. This task may be an import or parsing of a complex file.  Doing this activity with a normal page or with a webservice may incur in timeouts and obviously leave the user waiting the end of the task without a visible notification.

The solution attached to this post is an example of this case. I've created a service that is able to ping various web services to simulate a long-running task. You can change the logic in the core of the service, but this is not the point. The service is able to return updated status while it is processing the hosts it has to ping. Here is a screenshot of the interface.

Senza titolo-1

How it works

When you configure a service to be a Polling Duplex endpoint you are implicitly stating you will call its methods using a one-way paradigm. If you watch the code attached at the end of the article you may find that the methods of the service are all decorated with the IsOneWay property setted to true.

   1: [ServiceContract(
   2:         Namespace = "http://silverlightplayground.org/polling", 
   3:         CallbackContract = typeof(IPollingServiceClient))]
   4: public interface IPollingService
   5: {
   6:     [OperationContract(IsOneWay=true)]
   7:     void PingHosts(string[] hostsToPing);
   8: }

In a normal WCF service, saying a method is one-way imply that when you call it you have not to wait the end of its works. It will be accomplished asynchronously and you can forget the call and move forward to another activity. The runtime of WCF will start a thread for the call and it will run the task to complete.

In a polling duplex scenario the things act in a subtly different way. After the call has been started the client does not disconnect itself until a predefined timeout has expired. This timeout is something usual for a web server where every call need to be completed in a given amount of time for resource sharing reasons. But when the timeout expires the polling duplex client begins another connection and wait again for another timeout. This happen an indefinite number of times until the service or the client decide to stop the connection.

During this time the service thread owns an handle to the polling duplex client. This handle is called callback contract and is useful to the service to give notification to the client when something happen. When the service call a callback method the parts are swapped for a while so the server become a client and the client a server. What really happen in and http scenario is that the client is notified of the callback and it immediately disconnect from the webserver without waiting the next incoming timeout.

The flow I described means that the method called runs in a completely separated thread and is able to perform long-running operaton. So In my example I simply started a for-each loop to call the ping procedure once for every host I need to control.

   1: /// <summary>
   2: /// Does the task.
   3: /// </summary>
   4: /// <param name="argument">The argument.</param>
   5: public void PingHosts(string [] hostsToPing)
   6: {
   7:     IPollingServiceClient client =
   8:         OperationContext.Current.GetCallbackChannel<IPollingServiceClient>();
   9:  
  10:     foreach (string host in hostsToPing)
  11:     {
  12:         try
  13:         {
  14:             IPHostEntry pingTarget = Dns.GetHostByName(host);
  15:             IEnumerable<PingResult> results = pingTarget.Ping(10);
  16:             this.NotifyResult(client, host, results);
  17:         }
  18:         catch (Exception)
  19:         {
  20:             throw;
  21:         }
  22:     }
  23: }

Ever time a ping sequence is completed I notify the results to the client using the NotifyResults method on the clients. Once the method received the total expected results it is responsible of dropping the connection calling CloseAsync(). I you do not call this method the service continue the polling but there is not any working thread.

   1: if (progress.Value == this.Hosts.Count + 1)
   2: {
   3:     this.SetButton("Run", true);
   4:     this.Client.CloseAsync();
   5: }

Download: SilverlightPlayground.LongRunningTasks.zip (1,42MB)

Categories:  
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

SilverVNC - a VNC Viewer with Silverlight 4.0 RC

2010-03-15T19:07:30+01:00 by Andrea Boschin

vnc

I confess I wrote the code of this example few months ago, when only Silverlight 3.0 was on the scene, and I retained it for me because it was a beautiful example but not really useful. Since it uses a socket connection it is a little bit complicated to use it in real world scenario due the fact it needs a policy server, and it is restricted to few number of ports that does not have anything to do with VNC standard ports.

Finally, when I got the first bits of Silverlight 4.0 I decided it would be time to push it out to the folks, thanks to the new out-of-browser feature that now support full-trust installation. I've been persuaded from the opportunity of have a relaxed security on Socket connections meaning that I will be able to connect to any socket based service through a well known port and without having to install a policy server.

So, here is today SilverVNC, a basic implementation of the Remote Framebuffer protocol (RFB) written following the standard specifications (you can download them from the RealVNC website). I've implemented the protocol using the most recent build of UltraVNC to make tests.

As I've already said the implementation is basic. Differently from commercial version I only support the RAW encoding and avoid any type of compression. This simply because handling heavy socket communications with the asyncronous model of silverlight is a kind of bounce game that make simple things really complicated. So I preferred to give a simple example that let the user understand how it works.

How it works?

The core of the example is made of an RfbClient class that encapsulate all the logic needed to communicate with the server, decoding data and rasing events to the user interface. The class is made of methods that receive and send data to the socket. I will not detail the inner content of the class because the RFB protocol specifications are out of the scope of this article. You have only to be aware that while in OOB-Fulltrust the socket may be opened on every port and without any policy.

The main page of the application use the RfbClient to connect to the VNC server and pump data from the socket and decode. Every time RfbClient receive something it raises two types of event:

ResizeFrameBuffer : it mean the server notified a change of the size of the screen. It usually happens at the start of the connection to let the client resize the drawing area.

FramBufferUpdate: it mean the server detected a change on the screen so it cut out a rectangle and send it to the client. The event handler calculate the position of the rectangle on the drawing area and write it.

Here is how to handle these events:

   1: void Client_ResizeFrameBuffer(object sender, EventArgs e)
   2: {
   3:     this.MakeWindowProportional(this.Client.Server.Width, this.Client.Server.Height);
   4:     this.BitMap = new WriteableBitmap(this.Client.Server.Width, this.Client.Server.Height);
   5:     this.vnc.Source = this.BitMap;
   6: }
   7:  
   8: private void MakeWindowProportional(double width, double height)
   9: {
  10:     double proportion = width / height;
  11:     Application.Current.MainWindow.Height = Application.Current.MainWindow.Width / proportion;
  12:     Application.Current.MainWindow.Activate();
  13: }
  14:  
  15: private void Client_FrameBufferUpdate(object sender, FrameBufferUpdateEventArgs e)
  16: {
  17:     Rect rect = e.Rectangle;
  18:  
  19:     int x = 0;
  20:     int y = 0;
  21:  
  22:     foreach (uint color in e.Colors)
  23:     {
  24:         this.BitMap.Pixels[
  25:             (y + (int)rect.Y) *
  26:             this.Client.Server.Width +
  27:             (x + (int)rect.X)] = (int)color;
  28:  
  29:         if (++x == rect.Width)
  30:         {
  31:             x = 0;
  32:             y++;
  33:         }
  34:     }
  35:  
  36:     this.BitMap.Invalidate();
  37: }

Future implementations

There is some improvements I think will apply in the future. First of all I think the algorithm writing into the buffer might be more efficient than the code I showed here. My idea is to implement a MediaStreamSource to produce a video stream you can connect to a MediaElement. This should be better not only from the performances point of view but also may be simpler to be used by developers which needs to add a remote desktop viewer to his applications.

Another improvement is to implement the other compression algorithms. Probably I will implement RRE, CoreRRE and Hex. Finally I would like to transform the viewer in a full functional remote desktop client adding the capability to remote control the target machine. This shouldn't be too difficult.

Until then please have a try to this sample and give me any feedback you think useful to improve it.

Source: http://www.silverlightplayground.org/assets/sources/SilverlightPlayground.RFB.zip
Video: http://www.silverlightplayground.org/assets/video/SilverVNC.wmv
RFB Specifications: The RFB Protocol

Categories:   Networking | News
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

Chromeless Window for OOB applications in Silverlight 4.0 RC

2010-03-15T19:07:07+01:00 by Andrea Boschin

I think all of you are aware of the new useful features of Silverlight 4.0 beta released last November. I'm referringUntitled to a bunch of new improvements, affecting the out of browser applications, starting from the full-trust capabilities to the new Notification Window, and some little changes to the configuration of the window. The new release candidate of Silverlight 4.0 bring some news to the out of browser applications.

Until now we have a very little control over the window containing the application; we can configure the size and the positon on the screen and it is not possible to change them at runtime. With Silverlight 4.0 the Application class gain a new MainWindow proprty that expose a full set of tools to operate with the window. But this is not all the story. Using the project property we can also configure the window to be borderless and this let us draw our own chrome and manage window moving and resizing at runtime.

win The figure on the left show the configuration of the Window Style. It is available into the Out of browser settings window. Using NoBorder we can completely remove the default chrome of the window. Optionally we can also specify to have Round corners but there is not any configuration about the corner radius.

In the example attached to the end of this article I've created a simple control we can use to give a custom chrome to the window. The control has a template to customize the look and feel of the chromw and a buch of properties to define colors, and other aspects of the chrome. In the next paragraphs of this article I will show you how the control is built and how Silverlight let use easily customize the chrome in the release candidate bits.

The ApplicationWindow control

When we create a Silverlight application we usually define the MainPage.xaml as a UserControl, and this let us specify the markup of the page easily. Creating the ApplicationWindow control I decided to sobstitute it to the common UserControl so the control is defined as a ContentControl and we can change the markup like the code in this snippet:

   1: <controls:ApplicationWindow x:Class="SilverlightPlayground.GenericWindow.MainPage"
   2:                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:                             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:                             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:                             xmlns:controls="clr-namespace:SilverlightPlayground.Controls;assembly=SilverlightPlayground.Controls"
   7:                             Title="Tiny Browser"
   8:                             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">
   9:     <Grid x:Name="LayoutRoot" Background="WhiteSmoke">
  10:  
  11:     </Grid>
  12: </controls:ApplicationWindow>

The control is a normal Templated Control and in the generic.xaml I've specified the default aspect of the window chrome. Some of the properties of the elements inside the template have been binded to the properties of the ApplicationWindow control so it is simple to change the Border color, the background, the font etc. Some elements has been defined as parts so I can attach some events and add the expected behavior to the window. When the user drag the chrome the window has to move on the screen and when the user drags the corner the window has to be resized.

The release candidate of Silverlight give us two methods doing the great part of the work. They ad DragResize and DragMove. In the control I attach the MouseLeftButtonDown event and in the handler I call one of these method to start the corresponding action. Here is the code:

   1: void Chrome_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
   2: {
   3:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
   4:         Application.Current.MainWindow.DragMove();
   5: }
   6:  
   7: void ResizeHandle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
   8: {
   9:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
  10:         Application.Current.MainWindow.DragResize(WindowResizeEdge.BottomRight);
  11: }

The methods are so simple we really do not need to make any other action. After starting the action it detect the mouse and terminate the drag when the user release the button.

There is some other behaviors to implement. In the top right corner some buttons let the user close the window and operate like common windows minimizing and maximizing it. The MainWindow property has all the mehods and properties we need to make these buttons working. Here is some other code:

   1: void CloseButton_Click(object sender, RoutedEventArgs e)
   2: {
   3:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions && !args.Cancel)
   4:         Application.Current.MainWindow.Close();
   5: }
   6:  
   7: void MaximizeButton_Click(object sender, RoutedEventArgs e)
   8: {
   9:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
  10:     {
  11:         if (Application.Current.MainWindow.WindowState == WindowState.Normal)
  12:             Application.Current.MainWindow.WindowState = WindowState.Maximized;
  13:         else
  14:             Application.Current.MainWindow.WindowState = WindowState.Normal;
  15:     }
  16: }
  17:  
  18: void MinimizeButton_Click(object sender, RoutedEventArgs e)
  19: {
  20:     if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
  21:         Application.Current.MainWindow.WindowState = WindowState.Minimized;
  22: }

The video at the end of the article show how the window appear. The control is almost complete to emulate the common windows but there is some other features we can use to manage the window:

Top, Left, Width & Height can be user programmatically to change the size of the window at runtime, Activate bring the window in front of the other window and finally the TopMost property can make it standing on top of other windows.

Source: SilverlightPlayground.GenericWindow.zip
Video: ChromelessWindow.wmv

Using XmlDefinition and XmlPrefix to better organize namespaces

2010-03-15T19:06:42+01:00 by Andrea Boschin

I'm pretty sure you agree with me if I say that namespaces in XAML are the way to the hell. I mean the intricated jungle of xml namespaces, clr namespaces and prefixes you have to handle in a medium application. Every time you add a new control in the XAML, when it come from a different namespace, Visual Studio try to guess a good name for the prefix to use in XAML tags, and obviously it goes wrong.

The problem comes from the need of having a reference to an Assembly containing the clr namespace, and probably if you use only the wysiwyg editor of blend it is not a problem if the name is long and complicated, but when you start modify the markup by hand you often found that the same namespace has a different meaning in two different files.

The RC release of Silverlight 4.0 come with a solution to this great problem. The solution has the form of two attributes, valid in assembly scope, that grant the capability of having a xml namespace defined for a give clr namespace and a default prefix to be used from the IDEs. Here is an example of how to use them:

   1: [assembly:XmlnsDefinition("http://silverlightplayground.org/xaml/controls", "SilverlightPlayground.Controls")]
   2: [assembly:XmlnsPrefix("http://silverlightplayground.org/xaml/controls", "slpgControls")]

The XmlDefinition here specify a mapping between the xml namespace (the one starting with http://) and the clr namespace SilverlightPlayground.Controls. The XmlPrefix determine that the splgControls prefix have to be used every time a reference to this namespace have to be created. Here is the result of dragging an element to the designer surface:

   1: <UserControl x:Class="SilverlightPlayground.Test.MainPage"
   2:              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:              xmlns:slpgControls="clr-namespace:SilverlightPlayground.Controls;assembly=SilverlightPlayground.Controls"  
   7:              mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">
   8:     <Grid x:Name="LayoutRoot" Background="White">
   9:         <slpgControls:MyControl />
  10:     </Grid>
  11: </UserControl>

I don't know if this is the final solution, but I'm sure it will be important to have more organization in XAML.

Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

SilverlightShow EcoContest

2010-01-12T23:41:48+01:00 by Andrea Boschin

SilverlightShowEcoContest The team of silverlightshow.net announced today the first eco-contest. Obviously Silverlight is the focused technology but I really love the argument of the contest. The partecipants are invited to propose an application that will spread the word about climate change. After a failed of Copenaghen summit where the biggest and powerful countries have not been able to reach an agreement about the save of our planet there is for sure the need to embrace the cause and let people to be aware of this problem.

So this post would want to connect many people with the contest and hopefully with the climate changes argument. There is a great prize that I think a Silverlight enthusiast must not miss: A MIX10 invitation with hotel and travel expenses included.

The contest will end at 15 February so there is really few time to join an propose the applications. Here is the contest website:

http://contest.silverlightshow.net/

Categories:   News
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Writing a server-less conferencing client with Silverlight 4.0 UDP Multicast

2010-01-02T22:42:07+01:00 by Andrea Boschin

When I wrote my article about , I received many questions about writing application that communicate each other with this protocol. The reason for this request is that many people believe that Silverlight being a good platform for game developers due to its great graphical features and its simplicity, so a lot of them want to implement some kind of communication for on-line collaborative games.

Local connections have not been made for this kind of usage because them are available only for communication between application instances running in the same machine and it is not possible to use them to create gaming communications.

With Silverligth 4.0 the System.Net namespace hosts a new kind of socket communications, named UDP Multicast, that seems to be a possible solution for gaming applications but also for applications requiring fast communication between multiple clients, like conferencing applications also with video streaming support.

, also know as IP Multicast, is a well-known protocol that enables the ip infrastructure to replicate messages from multiple sources to be delivered easily to an undefined number of subscribers. The protocol works using a special class of IP addresses (224.0.0.0/4 for ipV4) where each single address represent a group of clients that is communicating each other relying on the network infrastructure for the replication of the messages. This enable the creation of client applications that do not need to have a central server where clients needs to connect using the common TCP sockets.

Like the common UDP protocol, IP Multicast is a not-connected protocol that does not guarantee the arrival of the messages and the order of delivery. So if you need a realiable channel the better is to rely on TCP sockets or you need to implement some kind of consistency check.

Writing a conferencing client

The first example I wrote to test the UDP Multicast feature is a simple conferencing client that enable people to join a multicast group and then send messages to the other members of the group.  The example you can download at the end of the article is very simplified and let the user specify an username (without checking if someone else is using the same username) and join the muklticast group. Then the user can type messages and send them to all the group members.

Silverlight 4.0 has two new classes to implement a multicast client

1) UdpSingleSourceMulticastClient let work with a single well-known source that is the unique client allowed to send to the group. This is the one-to-many communication. You can imagine to write a video source with this class and multiple clients to receive packets from it.

2) UdpAnySourceMulticastClient enables all the clients both to send and receive to or from the multicast group. This let you create something similar to a conferencing application where many-to-many connection is required.

When you use a multicast client the first thing you have to do is to join the group, using the known muticast ip address (ex: 224.0.0.1) and the port (ex: 3000). When the connection have been made you can start send and/or receive from the group. Differently from the TCP sockets with UDPMulticast you do not have a restricted set of ports to use. All the ports above of 1024 are available to the plugin.

Here is a snippet from my UDPAnySourceMulticastChannel I wrote for my example:

   1: public UdpAnySourceMulticastChannel(IPAddress address, int port, int maxMessageSize)
   2: {
   3:     this.ReceiveBuffer = new byte[maxMessageSize];
   4:     this.Client = new UdpAnySourceMulticastClient(address, port);
   5: }
   6:  
   7: public void Open()
   8: {
   9:     if (!this.IsJoined)
  10:     {
  11:         this.Client.BeginJoinGroup(
  12:             result =>
  13:             {
  14:                 this.Client.EndJoinGroup(result);
  15:                 this.IsJoined = true;
  16:                 Deployment.Current.Dispatcher.BeginInvoke(
  17:                     () =>
  18:                     {
  19:                         this.OnAfterOpen();
  20:                         this.Receive();
  21:                     });
  22:             }, null);
  23:     }
  24: }

In the constructor of the class, I've created an instance of the multicast client with the required address and port, then in the Open method I've called the BeginJoinGroup method that starts an asyncronous join request to the multicast address. As always the Silverlight's communication is asyncronous so when the callback is called I need to invoke the EndJoinGroup and then marshal the thread to the user interface with using the Dispatcher.

When the group has been joined you can start receiving and sending. This two actions are simultaneous because while you are receiving messages (or you are waiting to receive) you can also send messages to the group. So you have to invoke the BeginReceiveFromGroup method that starts listening for incoming packets and calls the callback method when something has been received. While the client is waiting for something to receive you can also call the BeginSendToGroup method to send something to the group. You have to be aware that when you send a packet to the group you will also receive the packet you sent because the multicast will replicate the message to all the joined clients.

   1: private void Receive()
   2: {
   3:     if (this.IsJoined)
   4:     {
   5:         Array.Clear(this.ReceiveBuffer, 0, this.ReceiveBuffer.Length);
   6:  
   7:         this.Client.BeginReceiveFromGroup(this.ReceiveBuffer, 0, this.ReceiveBuffer.Length,
   8:             result =>
   9:             {
  10:                 if (!IsDisposed)
  11:                 {
  12:                     IPEndPoint source;
  13:                     this.Client.EndReceiveFromGroup(result, out source);
  14:                     Deployment.Current.Dispatcher.BeginInvoke(
  15:                         () =>
  16:                         {
  17:                             this.OnReceive(source, this.ReceiveBuffer);
  18:                             this.Receive();
  19:                         });
  20:                 }
  21:             }, null);
  22:     }
  23: }
  24:  
  25: public void Send(string format, params object [] args)
  26: {
  27:     if (this.IsJoined)
  28:     {
  29:         byte[] data = Encoding.UTF8.GetBytes(string.Format(format,args));
  30:  
  31:         this.Client.BeginSendToGroup(data, 0, data.Length,
  32:             result =>
  33:             {
  34:                 this.Client.EndSendToGroup(result);
  35:             }, null);
  36:     }
  37: }

The UDPAnySourceMulticastClient class has some other interesting methods. You can send messages to the group specifing the destination so the network infrastructure will route the message to a single target. You can also block and unblock an IPAddress to prevent messages incoming from it to be received.

There is not a "Disconnect" or "Close" method but when you need to end the communication you can call the Dispose method of the client class. This will cause the pending receive to be dropped. It is important to have a flag set when the class is disposing because when the pending receive is dropped your callback is notified and you have to be aware that the client instance is not valid anymore and avoid to call the EndReceiveFromGroup method alse you will get an exception.

   1: /// <summary>
   2: /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
   3: /// </summary>
   4: public void Dispose()
   5: {
   6:     if (!IsDisposed)
   7:     {
   8:         this.IsDisposed = true;
   9:  
  10:         if (this.Client != null)
  11:             this.Client.Dispose();
  12:     }
  13: }

The client needs only to create an instance of the class an then call the Open method to join the multicast group. The channel then automatically starts listening from incoming packets and raise an event every time it detect something. So when the user hit the send button it I can call the Send() method to send a new packet and when the channel notify me about the arrival of a packet I add it to the logging listbox. I've added an AfterOpened and BeforeClose events to allow the client to send a message just after joining the group and before leaving it.

PolicyServer

Like other networking tools in Silverlight, the ip multicast requires something issuing a policy file. This is the sole server-side requirement for this protocol working fine. The policy server has to implement a two UDP messages system. The first message, sent by the client, is a datagram called "announcement" that asks the server to issue a policy file. When the server receive this message have to send an xml file that authorize to the client to communicate with a particular ip address and port. The mechanism is very similar to the TCP socket policy server but use an UDP messagging system.

To implement this server the best is downloading this project from MSDN code gallery. The project contains a working policy server that you can simply start from a console application or from a win32 service.

The drawbacks

The application I have included at the end of the article is very simple and demostrate the power of this messaging system, that was initially designed for effective video streaming. Unfortunately there is some drawbacks. First of all, also if I've entitled this example "server-less" this is true for the 99%. You need a policy issuer that is a little server, but it is not crucial for performance concerns. The system is really simpler than an always-connected TCP implementation and due to the nature of the UDP protocol really require less resources.

Another concern is about the security and realiability. The UDP protocol does not implements some infrastructure to avoid the ip spoofing and does not guarantee the packet delivery and the arrival order. In a real world solution you have to be aware of these limitation and take care of them. You have to write code to sign packets to know from whom they are issued and to handle packet loss and unordered delivery. This may be someway complex, but is a little price to pay for the effectiveness of this protocol.

Finally, the major drawback is that the most common firewalls manage to block this kind of traffic. If using a TCP socket server on a well known port is someway difficult due to the need of having firewall configurations, implementing a multicast is probably more complex specifically if you need to send the packets through the Internet. So in my opinion the most common scenario for this protocol to work is a local area network where you can manage to have firewalls and network infrastructure comply with it.

Download: SilverlightPlayground.UDPMulticast.zip (181 KB)

Categories:   Networking
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

A generic ViewModel to publish sets of objects

2009-12-16T22:14:18+01:00 by Andrea Boschin

The programming with the MVVM pattern often requires a proliferation of types because there are more Views that need a ViewModel than you might think. You can think that you need to associate a ViewModel only to simple blocks of your user interface, but while you are writing code you often understand that there are other cases where a ViewModel is required.

As an example while populating a DataGrid binding simple entities to the grid is not  good idea. A single row of a grid not only contains some data to be displayed but often may contain some commands, a link to be clicked, a button to delete an item and so on.

All these are cases where you need a ViewModel to correcty handle the binding and the related commands. So you have to create a new type, add a bunch of properties and some commands and finally populate the grid with instances of the new type. Then you will find someway difficult to route the command from the child ViewModel to the one that has generated it.

Simple is better.

In my recent applications I found a reasonable workaround that correctly handle the situation but avoid a proliferation of classes and as usual in this cases the solution comes from a generic type. The trick comes from the understanding that often in this scenario you have some properties of an entity to be binded and one or two commands to be raised. And in the most cases the command have to be handled by a parent ViewModel. Imagine to have a collection which is shown in a DataGrid and a delete command on each row; To remove the row, the command has to be catched by the ViewModel which is exposing the collection. So I decided to create a simple class named RowViewModel this way:

   1: public class RowViewModel<T,K> : ViewModel
   2:     where T : ViewModel
   3: {
   4:     /// <summary>
   5:     /// Initializes a new instance of the RowViewModel class.
   6:     /// </summary>
   7:     /// <param name="parent">The parent.</param>
   8:     /// <param name="payload">The payload.</param>
   9:     public RowViewModel(T parent, K payload)
  10:     {
  11:         this.Parent = parent;
  12:         this.PayLoad = payload;
  13:     }
  14:  
  15:     /// <summary>
  16:     /// Gets or sets the parent.
  17:     /// </summary>
  18:     /// <value>The parent.</value>
  19:     public T Parent
  20:     {
  21:         get { return this.GetValue<T>("Parent"); }
  22:         set { this.SetValue<T>("Parent", value); }
  23:     }
  24:  
  25:     /// <summary>
  26:     /// Gets or sets the pay load.
  27:     /// </summary>
  28:     /// <value>The pay load.</value>
  29:     public K PayLoad
  30:     {
  31:         get { return this.GetValue<K>("PayLoad"); }
  32:         set { this.SetValue<K>("PayLoad", value); }
  33:     }
  34: }

To simplify the creation of the collection property I've created a class RowViewModelCollection that inherits from the ObservableCollection. This allow me to declare the observable properties with a less verbose syntax:

   1: public class RowViewModelCollection<T, K> : ObservableCollection<RowViewModel<T, K>>
   2:     where T : ViewModel
   3: { }

Now we are ready to publish a DataGrid using this class. The RowViewModel exposes T as the parent ViewModel and K as the payload. This is the entity we want to display in the grid. So we can write a XAML similar to this:

   1: <data:DataGrid ItemsSource="{Binding Tasks}">
   2:     <data:DataGrid.Columns>
   3:         <data:DataGridTemplateColumn>
   4:             <data:DataGridTemplateColumn.CellTemplate>
   5:                 <DataTemplate>
   6:                     <HyperlinkButton cmd:Click.Command="{Binding Parent.DeleteTaskCommand}"
   7:                                      cmd:Click.CommandParameter="{Binding PayLoad}"
   8:                                      HorizontalAlignment="Center" VerticalAlignment="Center" >
   9:                         <Image Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" Width="16" Source="/Elite.TimeTracker.Client;Component/Images/delete.png" Stretch="Fill"/>
  10:                     </HyperlinkButton>
  11:                 </DataTemplate>
  12:             </data:DataGridTemplateColumn.CellTemplate>
  13:         </data:DataGridTemplateColumn>
  14:         <data:DataGridTextColumn Header="Cliente" Binding="{Binding PayLoad.Customer.Description}" />
  15:         <data:DataGridTextColumn Header="Ora" Binding="{Binding PayLoad.StartTime}" />
  16:         <data:DataGridTextColumn Header="Descrizione" Binding="{Binding PayLoad.Description, Converter={StaticResource ellipsis}}" />
  17:         <data:DataGridCheckBoxColumn Header="Chiam." Binding="{Binding PayLoad.IsPhoneCall}" />
  18:         <data:DataGridCheckBoxColumn Header="Compl." Binding="{Binding PayLoad.IsCompleted}" />
  19:     </data:DataGrid.Columns>
  20: </data:DataGrid>

In a couple of words we have:

ItemsSource="{Binding Tasks}" - This connect the DataGrid to a RowViewModelCollection declared in the parent ViewModel.

Binding="{Binding PayLoad.StartTime}" - This take advantage of the dot syntax of the DataBinding that allow to access complex properties of the binded objects. Remember that PayLoad is the instance of the entity to bind to the DataGrid so PayLoad.StartTime binds the StartTime property to the cell.

cmd:Click.Command="{Binding Parent.DeleteTaskCommand}" - This binds the click event of the HyperlinkButton to a command of the parent ViewModel.

cmd:Click.CommandParameter="{Binding PayLoad}" - This binding let me pass the entire entity the delegate command.

This tecnique simplifies the code required to handle the DataGrid. When a command is raised the parent ViewModel handle it and this reduce the need to use an EventBroker, and it gives a more simple and maintainable code.

Is this good only for DataGrids?

There are a lot of cases where you have to bind a collection to a control, the ItemsControl, the ListBox, and so on. Every time you encounter one of these cases you can obviously apply this tecnique. Of course it is useful only if you need to handle some commands, otherwise you can simply bind the entity directly to the control.
In the code I've attached to a my previous post - the -you can find a working sample of the workaround. 

Categories:   Databinding | TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Silverlight 4.0 beta released

2009-11-18T18:22:15+01:00 by Andrea Boschin

Download Sample Code: SilverlightPlayground.SL4BetaTestConsole.zip (89K)

 

During the Keynote of the PDC 2009 a new beta of Silverlight has been announced and made available. I think very few people did expect the early release of the version 4.0, and if you think in terms of number of new features compared with the time passed since the RTW of Silverlight 3.0 - only four months - you understand the big work made by one of the most prolific teams of Microsoft.

In the latest month I could play with the beta bits, and I've compiled a collection of the most important features coming in this release, to understand how them works and to release some working code to let people easily learn them. This collection is linked at the end of this post in the form of a self-explaining navigation application. The application contains eleven samples that show the features I list below:

Full Trust in Out of Browser: While detaching an application to out of browser now it is possible to give full trust to the installed application. This enable huge improvements: no need of cross domain policies, access to file system, no user-initiated dialogs. You can also use COM interoperability.

WebCam: Silverlight 4.0 introduce some new API to handle video and audio capture. This sample shows how to use the CaptureSource class to detect video devices and to capture live stream and snapshots from it. The same pattern can be used to capture audio sources

WebBrowser: This new control has been added to the Silverlight bits to enable the use of html hosting into Silverlight applications. The WebBrowser control is available only when the application is running out of browser so before running the sample you need to install the application

RichTextArea: Another new control let the user enter formatted code. The RichTextArea behave like a TextBox but it can host fonts, weights, styles, and entering graphic elements and links like you can do with a text editor. The sample show also how to read the content of the RichTextArea you can populate with XAML markup.

HTML Brush: Like using a media element to publish a video on a brush with the HtmlBrush it is possible to use the output of a WebBrowser control to render the brush. The use of this feature has some limits but the code works fine.

PrintDocument: In the development of Line of Business applications, sending documents to the printer is an useful feature. Silverlight 4.0 introduce a new PrintDocument that enable sending elements of the Visual Tree to the printer.

Righ Mouse Button: In the previous releases the context menu of Silverlight prevent the use of the Right mouse button. In this release you can intercept this button and attach the logic you need. In the sample you can use left and right buttons to change the size of the circle. If you click outside the circle the normal context menu will be displayed.

DataBinding to DependencyObject: In the current version the DataBinding between elements is available only when the target inherits from FrameworkElement. This limit prevent, as an example, to bind multiple a RotateTransform to a single Slider. In Silverlight 4.0 this limit has been overcome and now it is possible to bind DependencyObjects. This is a great step in the compatibility with WPF.

Improvements to Binding: The binding markup extension has been enriched with a new set of properties which simplify the development. This include StringFormat, FallbackValue and TargetNullValue.

Commands: The controls inheriting from ButtonBase has acquired two new properties, Command and CommandParameter. It is a tiny step in the direction of MVVM programming.

Drag & Drop: With this release it is possible to detect dragging of elements on the application surface. The sample read the filename, la last access date and the size of the stream.

Notification Window: Desktop application can show a popup in the tray bar of Windows. This now is available also in Silverlight out of browser applications.

These are a huge set of features for the short period of time where they were developed. I hope many of you will find useful the code I've linked to this post. If you need help to understand the samples feel free to contact me through the contact form.

Download: SilverlightPlayground.SL4BetaTestConsole.zip (89K)

Categories:   News | Demo
Actions:   E-mail | del.icio.us | Permalink | Comments (3) | Comment RSSRSS comment feed