Silverlight et HttpHandler

Http handlers are very interesting for several scenarios:

  • Security: when you want to check custom authentication or authorization;
  • Logging: when you want to trace requests to a specific page, resource, …;

In a Silverlight project based on Composite Application Guidance for Silverlight (also known as Prism) you can take advantage of ModuleCatalog and HttpHandler.

I’ll to explain you the advantage of using those 2 technologies in a dummy example.

Scenario

For example, my application is built on Composite Application Guidance for Silverlight. When a client connect to the Silverlight application I really want him to get just the code (code in xap ) he needs. For example, if the client belongs to the “user” role, I don’t want him to download the xaps needed by “administrator” role.

In Composite Application Guidance for Silverlight, you can take advantage of Module Catalog to load xap files from different locations.

Code Snippet

  1. <Modularity:ModuleCatalogxmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:Modularity="clr-namespace:Microsoft.Practices.Composite.Modularity;assembly=Microsoft.Practices.Composite">
  2.   <Modularity:ModuleInfo Ref="ModuleZ.Silverlight.xap" ModuleName="ModuleZ" ModuleType="ModuleZ.ModuleZ, ModuleZ.Silverlight, Version=1.0.0.0" />
  3. </Modularity:ModuleCatalog>

In fact, in the Ref attribute of ModuleInfo element, you can put an other location,

for example “../secured/ModuleZ.Silverlight.xap”. Instead of getting it from ClientBin folder, you will get the xap from “secured” directory.

For more information on Module Catalog.

Step 1 : Creation of the HttpHandler

In a web application, insert a new class named for example MyHandler. This class have to implement IHttpHandler interface.

Code Snippet

  1. public class MyHandler : IHttpHandler
  2.     {
  3.         /// <summary>
  4.         /// Constructor
  5.         /// </summary>
  6.         public MyHandler()
  7.         {
  8.  
  9.         }
  10.         /// <summary>
  11.         /// Process request
  12.         /// </summary>
  13.         /// <param name="context"></param>
  14.         public void ProcessRequest(HttpContext context)
  15.         {
  16.             // Here is the code of your implementation
  17.             ...
  18.      
  19.         }
  20.         /// <summary>
  21.         /// Enable pooling
  22.         /// </summary>
  23.         public bool IsReusable
  24.         {
  25.             get { return true; }
  26.         }
  27.     }

This interface contains 2 methods :

ProcessRequest : method containing your logic;

IsReusable : method informing that the pooling is enabled;

Step 2 : Implementation of your logic

You just have to develop the logic.

Code Snippet

  1. public class MyHandler : IHttpHandler
  2.     {
  3.         public MyHandler()
  4.         {
  5.         }
  6.         public void ProcessRequest(HttpContext context)
  7.         {
  8.             string path;
  9.             // Get the requested xap file name
  10.             string expectedFile = context.Request.Url.Segments[context.Request.Url.Segments.Length - 1];
  11.  
  12.             // Get the desired xap file
  13.             if (HttpContext.Current.User.IsInRole("Admin"))
  14.                 path = string.Format(@"c:\MyApplication\Admin\{0}",expectedFile);
  15.             else
  16.                 path = string.Format(@"c:\MyApplication\User\{0}", expectedFile);
  17.  
  18.  
  19.             // Content Type
  20.             context.Response.ContentType = "application/x-silverlight-2";
  21.  
  22.             // Return the xap file
  23.             using (Stream data = File.OpenRead(path))
  24.             {
  25.  
  26.                BinaryReader reader = new BinaryReader (data);
  27.  
  28.                 const int size = 4096;
  29.                 byte[] bytes = new byte[4096];
  30.                 int numBytes;
  31.                 while((numBytes = reader.Read(bytes, 0, size)) > 0)
  32.                     context.Response.OutputStream.Write(bytes, 0, numBytes);                  
  33.                
  34.             }
  35.             context.Response.OutputStream.Flush();
  36.      
  37.         }
  38.         public bool IsReusable
  39.         {
  40.             get { return true; }
  41.         }
  42.     }

In the ProcessRequest method, first of all, get the name of the desired xap.

Depending on the user role, define the correct path and than return the xap to the client application.

“C:\MyAplication\Admin\”  -> folder containing admin xap

“C:\MyAplication\User\”  -> folder containing user xap

Do not forget to set the ContentType to "application/x-silverlight-2".

Of course you can optimize the xap with a caching mechanism, but you have to define a mechanism to refresh it. It can be interesting when you deploy a new xap ;-)

Step 3 : Register your http handler in your web application & Test

In the web.config file you just need to register your handler (sample for IIS 7.0 running in Integrated mode):

Code Snippet

  1. <system.webServer>
  2.     <handlers>
  3.         <add verb="*" path="Secured/*.xap" name="MyHandler" type="MyNamespace.MyHandler, MyAssembly"/>
  4.     </handlers>
  5. </system.webServer>

In this case, the handler will be executed for each verb and every time I’ll request a xap in Secured directory. No need to create the Secured folder.

For other IIS, I suggest you to read this article https://msdn.microsoft.com/en-us/library/ms228090(VS.100).aspx.

To test your handler, you just have to open IE and to execute your request:

https://mycomputer/MyApplication/Secured/test.xap

Finally, you just have to run your Silverlight application. :-)

Conclusion

This scenario can be solve with several other methods. My goal is just to present you the collaboration of those 2 technos.