Hide menu Last updated: Mar 25 2013

Table of Contents


URL rewriting involves functionality that modifies a web URL’s appearance. Rewritten URLs, also known as “Friendly” or Search Engine Friendly (SEF) URLs, are used to provide shorter and more relevant-looking links to web pages. EPiServer CMS supports routing of incoming URLs and rewriting of outgoing URLs. This is the mechanism behind friendly URLs where a visible link is rewritten to something more intuitive and user friendly than is usually the case. The technique adds a degree of separation between the files used to generate a web page and the URL that is presented.

By default EPiServer CMS routes incoming and outgoing traffic by using the built-in routing in .NET. When using WebForms a FriendlyUrlProvider is used to rewrite links in the the outgoing html (in CMS version 6 and older the FriendlyUrlProvider was also handling incoming request). To use routing when using WebForms the URL rewrite provider must be set to HierarchicalUrlRewriteProvider and the HTTP module for URL rewriting should be EPiServer.Web.RoutingUrlRewriteModule. Any other UrlRewriter implementation will not use routing to handle incoming request but instead the previously used UrlRewrite functionality. MVC implementations will not use the UrlRewrite provider, in that case the outgoing URLs are constructed directly in views/controllers using for example HtmlHelper extension methods.

Default Routes

There are several routes registered by default. The Shell modules will have routes registered to support routing to for example gadgets. The CMS will also register a number of routes by default. The CMS routes are registered in GlobalBase during initialization, it is possible to override the RegisterRoutes method in Global.asax.cs to customize the registered routes or add additional routes. The namespace EPiServer.Web.Routing contains some extension methods for the class RouteCollection. Those extension methods can be used to register a route on the site or register a partial router, see Partial Routing. Among the default routes there will be one set up for routing simple address, one for each site (can be several in enterprise scenarios), and one that routes pages/content from the root (that is pages/content not under any start page). The “ordinary” MVC route “{controller}/{action}” is also registered to support partial request through for example Html.RenderAction, however direct browsing to those routes are prevented. The routes are registered in the order above. This is important because the first route will look if the URL matches its route, and if it does, the page will be routed through that route. If the URL does not match the first route, the next route will get its chance.

MVC and Web Forms

A URL can be routed through the routing framework for both MVC and web forms. The routing will first from the URL locate the content routed to. After the content has been located, the framework will query the EPiServer.Web.TemplateResolver instance which template that should be used to render the request. The template can be either a MVC controller or a WebForm. Then depending on if the template is a WebForm or a MVC controller a suitable httpHandler is set to handle the request. If no content is found that matches the URL or if no template is found that matches the routed content a 404 is returned.

Extending Routing

Routing can be extended in several levels. There are events exposed both during incoming routing and creation of outgoing URLs that can be used to customize routing. It is also possible to modify the default URL pattern for content routing to handle part of the URL. And you can also add your own routes.


The class EPiServer.Web.Routing.ContentRoute (that is repsonsible for routing to content) exposes static events RoutingContent, RoutedContent that are raised during incoming routing. RoutingContent are raised before the default routing implementation is executed and in an event handler can for example the content that match the request be set. RoutedContent are raised after the default routing has executed and in an event handler can for example the routed content be replaced. During outgoing URL generation are the events CreatingVirtualPath and CreatedVirtualPath raised where event handlers can modify the URLs generated.

Modifying ContentRoute

The built in content routing is based on that an URL pattern is registered where each pattern is handled by an implementation of an interface EPiServer.Web.Routing.Segments.ISegment. It is possible to implement custom ISegment types and register them as part of the content routing.

By default content routing is registered with a pattern as “{language}/{node}/{partial}/{action}”. The {language} part says that in the URL there might first be an optional part that states the language. The {node} part is used to specify the CMS page/content in the URL, it will follow the site structure and contain all page names after the start page on the site, down to the requested page. For example, in the following structure “start > news > firstNews”, the URL part handled by {node} part would be “/news/firstNews”. If there is something remaining in the URL after the page/content routing any registered EPiServer.Web.Routing.IPartialRouter that matches the type of located page will get a chance to route the remaining of the URL. Then at last the any remaining part is checked if it is a valid action for a MVC controller. If the requested action would be “myAction” (MVC), the whole URL would be "http://mySite/news/firstNews/myAction".

The MapContentRoute extension method takes the name of the route, the URL pattern, and default values as arguments. Each part in the URL pattern for content routing (for example {node} or {partial}) is handled by an implementation of EPiServer.Web.Routing.Segments.ISegment. It is possible to extend content routing with own ISegment implementations.

The following example shows how to add a route:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;

using EPiServer.Web.Routing;

namespace CodeSamples
    /// <summary>
    /// Code sample class containing cref examples on how to register a route
    /// </summary>
    public static class RegisterCustomRouteExample
        /// <summary>
        /// Register a route which makes 'shop/' in the beginning of the url valid.
        /// This method should only be called when the site starts, for example in 'Application_Start' (Global.asax).
        /// </summary>
        public static void RegisterShopRoute()
            // Register a route, which will make all url:s with 'shop/' before page names route to the page last in the list of page names
            // For example, http://mySite/shop/News/ListOfNews/FirstNews/ will route to the 'FirstNews' page. 

            RouteTable.Routes.MapPageRoute(name: "customRoute",
                url: "shop/{node}/{partial}/{action}",
                defaults: new { action = "index" });

Implementing a Custom Route

It is also possible to add custom Route implementations. The order of the routes are important since the first route that handles a request will prevent that following routes get a chance to route the request. So when registering custom routes it is important to decide wether it should be registered before or after the default routes.