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
- <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">
- <Modularity:ModuleInfo Ref="ModuleZ.Silverlight.xap" ModuleName="ModuleZ" ModuleType="ModuleZ.ModuleZ, ModuleZ.Silverlight, Version=1.0.0.0" />
- </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
- public class MyHandler : IHttpHandler
- {
- /// <summary>
- /// Constructor
- /// </summary>
- public MyHandler()
- {
- }
- /// <summary>
- /// Process request
- /// </summary>
- /// <param name="context"></param>
- public void ProcessRequest(HttpContext context)
- {
- // Here is the code of your implementation
- ...
- }
- /// <summary>
- /// Enable pooling
- /// </summary>
- public bool IsReusable
- {
- get { return true; }
- }
- }
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
- public class MyHandler : IHttpHandler
- {
- public MyHandler()
- {
- }
- public void ProcessRequest(HttpContext context)
- {
- string path;
- // Get the requested xap file name
- string expectedFile = context.Request.Url.Segments[context.Request.Url.Segments.Length - 1];
- // Get the desired xap file
- if (HttpContext.Current.User.IsInRole("Admin"))
- path = string.Format(@"c:\MyApplication\Admin\{0}",expectedFile);
- else
- path = string.Format(@"c:\MyApplication\User\{0}", expectedFile);
- // Content Type
- context.Response.ContentType = "application/x-silverlight-2";
- // Return the xap file
- using (Stream data = File.OpenRead(path))
- {
- BinaryReader reader = new BinaryReader (data);
- const int size = 4096;
- byte[] bytes = new byte[4096];
- int numBytes;
- while((numBytes = reader.Read(bytes, 0, size)) > 0)
- context.Response.OutputStream.Write(bytes, 0, numBytes);
- }
- context.Response.OutputStream.Flush();
- }
- public bool IsReusable
- {
- get { return true; }
- }
- }
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
- <system.webServer>
- <handlers>
- <add verb="*" path="Secured/*.xap" name="MyHandler" type="MyNamespace.MyHandler, MyAssembly"/>
- </handlers>
- </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.