How do I always keep my URLs in lowercase?

Posted on

Question :

I want all URLs on my site to be lowercase to help with SEO and for consistent link sharing.

How can I do this?


Answer :

You can use IIS URL Rewrite . To use on a server just download and install. Shared hosts usually include this module.

With this module installed just set up rules.

To convert everything to small, you can use this rule.

    <rule name="LowerCase" stopProcessing="true">
      <match url=".*[A-Z].*" ignoreCase="false" />
        <add input="{REQUEST_METHOD}" matchType="Pattern" pattern="GET" ignoreCase="false" />
      <action type="Redirect" url="{ToLower:{R:0}}" redirectType="Permanent" />

It will detect if there are uppercase letters in the URL, if so it will redirect to the lowercase equivalent. Note that this rule only redirects the GET method, thus preventing it from preventing an incorrect external form or request.

And for your code to generate URLs in minuscule you should set the following property to true (available only in .NET 4.5):

public static void RegisterRoutes(RouteCollection routes)
    routes.LowercaseUrls = true;

If you do not have IIS URL Rewrite you can do it by code, in Global.asax.cs

protected void Application_BeginRequest(object sender, EventArgs e)
    if (Regex.IsMatch(Request.Url.OriginalString, @"[A-Z]"
        && HttpContext.Current.Request.HttpMethod == "GET")
        Response.Status = "301 Moved Permanently";
        Response.AddHeader("Location", Request.Url.OriginalString.ToLower());


I use a slightly different method to do, and avoid modifying the QueryString to avoid problems, sometimes the parameter may need to be case sensitive or if it is a bundle or urls that can be case sensitive and make no difference in that the user views

 protected void Application_BeginRequest(object sender, EventArgs e)
        var isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get");
        if (!isGet || HttpContext.Current.Request.Url.AbsolutePath.Contains(".")) return; // não desejo redirecionar em caso de POST, ou imagens/css/js/etc
        if (HttpContext.Current.Request.Url.AbsolutePath.Contains("/Content/") || HttpContext.Current.Request.Url.AbsolutePath.Contains("/Scripts/") || HttpContext.Current.Request.Url.AbsolutePath.Contains("/bundles/") || HttpContext.Current.Request.Url.AbsolutePath.Contains("/lightview/")) return; // proteção adicional ao arquivos das pastas content (css) e scripts (js)
        var lowercaseUrl = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
        if (!Regex.IsMatch(lowercaseUrl, @"[A-Z]")) return;
        lowercaseUrl = lowercaseUrl.ToLower() + HttpContext.Current.Request.Url.Query; // Não devo alterar o case da querystring
        Response.Status = "301 Moved Permanently";
        Response.StatusCode = (int)HttpStatusCode.MovedPermanently;
        Response.AddHeader("Location", lowercaseUrl);


This avoids some problems and leaves only the necessary in the default.
I also added the 301 header so I did not have issues with Google


Leave a Reply

Your email address will not be published. Required fields are marked *