August 21, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Extend the Flexibility and Functionality of SharePoint with HTTP Modules and Handlers

  • March 27, 2009
  • By Gustavo Velez
  • Send Email »
  • More Articles »

HttpModules for SharePoint 2007

HttpModules allow for the implementation of richer methods than HttpHandlers. The former permits implementing 'IsReusable' and 'ProcessRequest', as explained, but HttpModules can utilize different types of events such as 'AcquireRequestState', 'AuthenticateRequest' and 'AuthorizeRequest', and most importantly, 'Begin/EndRequest'. Another fundamental difference between modules and handlers is that the latter execute in any type of request, regardless of the file extension: this opens the door to create code that always works in the system, whether or not the page or request is sent to the server.

To use HttpModules in SharePoint, as mentioned, the most common events are 'BeginRequest' and 'EndRequest'. These two events allow catching the request before SharePoint processes it and after the response was processed but before it is sent to the client.

The most basic example of a HttpModule is one that eliminates all the responses in the system. In reality this is not practical, its usefulness is that it can be modified to, for example, create a message page if the Portal is in maintenance. Remember that the module executes in all requests, so that regardless of the URL used, the response is always the maintenance page. The source code for the module might look like this:

using System;
using System.Web;
 
namespace HttpModule_01
{
    public class Class1 : IHttpModule
    {
        public void Init(HttpApplication context) 
        { 
           context.BeginRequest += new EventHandler(BeginRequest); 
        } 
 
        private void BeginRequest(object sender, EventArgs e) 
        {
           HttpContext.Current.Server.Transfer(
                         "/_layouts/maintenance.html", false);
        } 
 
        public void Dispose() 
        { 
            // TODO:  Add Implementation of CustomModule.Dispose 
        }
    }
}

As you can see the real code consists of only two lines: in the initialization event is a reference to the method 'BeginRequest' and inside the routine, a code line that makes the request transfer to a maintenance page. The class inherits from the IHttpModule interface and a reference to 'System.Web' is required. The 'Dispose' method is obligatory for implementation and as a good programming rule, the method deletes the created and unused objects.

The project is realized in Visual Studio as a 'Class Library' and the assembly needs to be signed with a secure name. After compilation, the DLL can be copied to the bin directory of the respective Web application in the root of IIS (C:InetpubwwwrootwssVirtualDirectories80bin, for example). The assembly may also be installed in the GAC, but to restrict its scope to a specific Web application it is recommended to install it in the Bin directory. To ensure that SharePoint acknowledges the module, the next code lines are added in the 'web.config' file of the Web Application in IIS, under the 'HttpModules' section:

<add name='HttpModule_01' type='HttpModule_01.Class1, HttpModule_01, 
     Version=1.0.0.0, Culture=neutral, PublicKeyToken=97bc1af85e70ceb9' />

Replace the correct values for name, type and KeyToken. As you can see in the 'HttpModules' section of the 'web.config' file, SharePoint has some modules already configured by default: cache, authentication, authorization and roles management. The order of the statements in the section is very important: authentication before authorization, and both before roles assignment; the order must be preserved to eliminate any disruption to the internal working of SharePoint. Normally if you create your own module, it is registered at the end of the section to prevent alterations to the system, however this is not obligatory: in the case of the maintenance page, it is possible that the module is registered at the beginning, because authentication and authorizations are unnecessary.

A typical utilization of the 'AfterRequest' event is to modify the response of SharePoint and display information in each page of the Portal, for example, a footnote pertaining to 'Conditions of Disclaimer':

using System;
using System.Web;
 
namespace HttpModule_02
{
    public class Class1 : IHttpModule
    {
        public void Init(HttpApplication context) 
        { 
           context.EndRequest += new EventHandler(EndRequest); 
        } 
 
        private void EndRequest(object sender, EventArgs e) 
        {
            HttpApplication myHttp = (HttpApplication) sender;
            myHttp.Context.Response.WriteSubstitution(
                new HttpResponseSubstitutionCallback(WriteText));
        }
 
        static protected string WriteText(HttpContext context)
        {
            return 'This is a disclaimer';
        }
 
        public void Dispose() 
        { 
            // TODO:  Add Implementation of CustomModule.Dispose 
        }
    }
}

In this case the 'EndRequest' event is initiated to modify the complete response. The 'EndRequest' method creates an object containing the response and calls a delegate method ('WriteText') using the 'WriteSubstitution' method that creates the text.

Note that the text appears after the '</body></html>' section in the HTML code. This does not create problems for a disclaimer or footnote because the result is expected and modern HTML navigators can render it without problem, however the code does not satisfy the w3.org specifications. A solution might be to save the complete HTML response temporarily in a binary stream, modify it using concatenation or a regular expression, remove the original result and send the modified stream. The purpose of the example is to show the use of modules in SharePoint, the implementation details are added following individual specifications. Also take care to save the disclaimer text outside the module source code otherwise if there are changes to the text, the code must be altered, compiled and installed again.

Although the most common events used with SharePoint are 'BeginRequest' and 'EndRequest', there are other ones designed to realize requirements. For example, to change a Master Page dynamically, the event 'PreRequestHandlerExecute' is used because it initiates precisely before the ASP.NET framework starts to execute the page; if you use a different event, the Master Page is already mixed with the content and it is impossible to change the generated HTML code. One possible source code to make this change is:

using System;
using System.Web;
using System.Web.UI;
 
namespace HttpModule_03
{
    public class Class1 : IHttpModule
    {
        public void Init(HttpApplication context) 
        { 
            context.PreRequestHandlerExecute += new EventHandler(ChangeRequest); 
        } 
 
        private void ChangeRequest(object sender, EventArgs e) 
        {
            Page myPage = HttpContext.Current.CurrentHandler as Page;
            if (myPage != null)
                myPage.MasterPageFile = '~/Master1.master';
        }
 
        public void Dispose()
        {
            // TODO:  Add Implementation for CustomModule.Dispose 
        }
    }
}

The possibilities of this module are extensive. In a default implementation, SharePoint allows defining only one Master Page for each Site Collection, and it is configured in the same way for all users in the Collection. 'Themes' is a method to ensure personalization in the Collection pages and allows for personal configurations, however the changes are limited to modifications in the CSS styles. With this module it is possible to modify pages based in user groups, including individual users; it also allows each user to have their own interface.

Continuing with the examples, a convenient HttpModule that can improve the user experience is the creation of a page with improved error information. By default, SharePoint displays a page indicating an error occurred, but does not provide additional information. A module can intercept the requests through IIS and capture errors:

using System;
using System.Diagnostics;
using System.Web;
 
namespace HttpModule_04
{
    public class Class1 : IHttpModule
    {
        public void Init(HttpApplication context) 
        { 
            context.Error += new EventHandler(MyError); 
        } 
 
        private void MyError(object sender, EventArgs e) 
        {
            Exception[] AllMyErrors = HttpContext.Current.AllErrors;
 
            foreach (Exception ex in AllMyErrors)
            {
                EventLog myLog = new EventLog();
                myLog.Log = 'Application';
                myLog.Source = 'My HttpModule';
               myLog.WriteEntry('An error has occurred');
            }
 

           HttpContext.Current.Server.ClearError();
           HttpContext.Current.Server.Transfer('/_layouts/MyErrorPage.aspx');
        } 
 
        public void Dispose() 
        { 
            // TODO:  Add Implementation of CustomModule.Dispose 
        }
    }
}

The 'Error' event in the module executes the 'MyError' routine that makes an array of exceptions. Each error in the array is examined to make an entry in the Windows Log Viewer. Finally the errors in the context are eliminated and a redirection to the error pages is implemented. This page displays the error type and a message indicating the steps to follow. The message used in the code is simple but it may contain the required information. In a similar way, errors can be saved to an external system (database or SharePoint List) and complementary actions taken, such as send an email to the system administrator.

Conclusions

HttpHandlers and HttpModules allow developers to extend the flexibility and functionality of SharePoint. Developers have been slow in recognizing their possibilities so they have not been used extensively. Hopefully this will change. HttpHandlers and HttpModules are easy to program and can be widely implemented in the system, so they are a useful tool to add to the SharePoint developer's toolbox.

The author

Gustavo Velez is a Manager in the Solutions Development department at Avanade Netherlands, a global consultancy company. He has many years experience developing Windows and Office applications, and more than six years of daily programming experience with SharePoint. The author's articles can be found in many of the leading trade magazines in English, Dutch and Spanish. He is also pleased to be Webmaster of http://www.gavd.net, the only Spanish-language site dedicated to SharePoint. Spanish-language readers may want to consult Velez's book, Programación con SharePoint 2007. In March, Gustavo's English-language book on Workflows is scheduled for publication. Velez has been awarded MVP status in the area of SharePoint MOSS.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel