Click here to Skip to main content
15,887,214 members
Articles / Web Development / ASP.NET
Tip/Trick

Response.Redirect Interceptor

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
14 Nov 2014CPOL2 min read 11.9K   3  
IHttpModule intercepting EndRequest to convert URL passed to Response.Redirect.

Introduction

ISAPI module to intercepts IIS response.redirect calls and convert the URL to lowercase to avoid 302 or 301 Status code not good for SEOs.

Background

An application containing more than 100 files having code using Response.Redirect to achieve redirection from a page to another page in ASP.NET. If passed urls to Response.Redirect are case insensitive and SEOs complaining for them to be in lowercase.

So quick and dirty solution could be go in all code files and convert those URLs passed to Response.Redirect method to lowercase. But obviously this not a smart solution. More sophisticated and quick solution is to intercept all redirected Requests and convert their redirected URLs to lowercase.

After googling and going to MSDN and also on StackOverflow manage to write a IHttpModule while same could be done in global.asax file. But for separation of concern IHttpModule is better. For a understanding of IHttpModule please refer to this article. I am putting both logic below. Please always be careful in implementing any thing in IIS pipeline It is good to have CODE REVIEW with Team Lead and other senior developers, other wise there could be very unpredictable results and performance degrading issues could be raised.

Main logic

From MSDN documentation It is quite clear that Response.Redirect is internally setting Location Header in Response object and luckily, not only this header is accessible but also could be alter. It means that I have to get the value of Location header and then call lower method on it and then set it back to header.

C++
  string redirectedLocation = context.Response.Headers["Location"];
  context.Response.Headers["Location"] = redirectedLocation.ToLowerInvariant();

And there is also a property of Response object indicating redirection for the current request

C#
IsRequestBeingRedirected

Global.asax

C#
void Application_EndRequest(object sender, EventArgs e)
    {
        HttpApplication application = sender as HttpApplication;
        HttpContext context = application.Context;

        if (context.Response.IsRequestBeingRedirected)
        {
            string redirectedLocation = context.Response.Headers["Location"];
            context.Response.Headers["Location"] = redirectedLocation.ToLowerInvariant();
        }
    }

IHttpModule

As mentioned above IHttpModule is cleaner and more maintainable as well. Please put contants files to avoid magic strings in a separate file some where else in project better is to have them project specific.

namespace CustomizeIISPipeline
{
    public class RedirectorInterceptorModule : IHttpModule
    {
        public RedirectorInterceptorModule()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        
        public void Init(HttpApplication application)
        {
            application.EndRequest +=
              (new EventHandler(this.RedirectInterceptor));
        }

        private void RedirectInterceptor(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;
            HttpContext context = application.Context;

            if (context.Response.IsRequestBeingRedirected)
            {
                string redirectedLocation = context.Response.Headers[AppConstants.RESPONSE_LOCATION_HEADER];
                context.Response.Headers[AppConstants.RESPONSE_LOCATION_HEADER] = redirectedLocation.toLowerInvariant();
            }

        }
        public void Dispose(){}
    }
    public static class AppConstants
    {
        public const string RESPONSE_LOCATION_HEADER = "Location";
    }
}

 

web.config entry for above module

<system.webServer>
  <modules>
      <add name="RedirectorInterceptorModule" type="CustomizeIISPipeline.RedirectorInterceptorModule"/>
     </modules>
</system.webServer>

 

Points of Interest

Though above is a remedy for the situation I and mine team is confronting with because of not well planned coding stratedgy. However, a better solution could be that we always have a Wrapper class whenever utliziing underlying framework specially for URL related functionality and any 3rd Party consumption in our applications.

So rule of thumb,

"Having wrapper will avoid regret in future for changes to make"

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Better Homes LLC, Dubai
Pakistan Pakistan
"A student learning to live with best patterns for mortal life of this world, to become successful in eternal life after this world. Please all try to find out what is the purpose of us of being here in this world."
- Ummati Mohammad Sal lal laho Wsslm

Have done software development more than a few years for living.

Comments and Discussions

 
-- There are no messages in this forum --