EPiServer 7 Routing For Dummies

On one of my first EPiServer 7 projects was to implement a blog within Episerver.  When you work with concepts like categories, tags and blog posts you might not want these assets living inside your content tree like the example below:

episerver_blog_samplesite_screenshot6

In these types of situations, you need to start looking into custom routes, partial routers and custom segments.. however understanding routing can be challenging at first as Episervers routing doesn’t work exactly like MVC’s routing does.

Using standard MVC is pretty easy going but using EPiServer I found a few unexpected features along the way so I thought I’d write them up for future reference.

MVC Routing Vs EPiServer Routing

First thing you should know there is a different between standard MVC routing and EPiServer routing.  A normal MVC route can be seen below:

protected void Application_Start()
{
ViewEngines.Engines.Add(new CustomViewEngine());
AreaRegistration.RegisterAllAreas();
var routes = RouteTable.Routes;
routes.MapRoute(
"Default",                                              // Route name
"{controller}/{action}/{id}",                           // URL with parameters
new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);
RegisterRoutes(routes);
}

What this is doing is telling MVC to set a default match on a controller called home and an action method called index. A matching url would be

www.website.com/Home/index

or

www.website.com

Now, when we use Episerver and Url’s, the routing is all done within Episerver itself. There is no direct correlation between a controller and the page we want to access in the page tree.  For this reaons Episerver does some behind the scenes magic and replaces the concept of {controller} with {node} or a content reference.

In an Episerver website, if we still want to do things like create a form that directs to a controller, we can but we have to add in custom routing.  Out the box Episerver does not support controller/action method routing like a normal MVC site.

This can be really confusing at first to get your head around as you expect something to work one way and it doesn’t.

Instead a more Episerver default route might be:

var routes = RouteTable.Routes;
routes.MapRoute(
name:"myRoute",
url:"{language}/{node}/{action}",
defaults:new { action = "Index" }
);

So to break the MapRoute parameters down:

  • name:”myRoute”myRoute is the name I choose for the route.  This can be anything you want it to.  It’s the name we register in MVC that no one will ever see
  • url:”{language}/{node}/{action}” : This breaks down the Url into things called segments. For each segment in the URL map it is in sequential order of the parameters. The following Url:www.website.com/en/SearchPage

    would translate into

    {language} = en
    {node} = 12 (this is the episerver page id. This is the magic that swaps MVC from using the standard controller mapping discussed above.
    {action} = Index. In our case as we’ve defined a default action for index so we can make it optional in the Url.

    EPiServer has a few special keywords but you can make any up yourself. See How to make a Site Search in Episerver for more information to do this.

  • defaults: This section maps any default values that should be applied in case it’s omitted from the Url.

So if we did something like this

var routes = RouteTable.Routes;
routes.MapRoute(
name:"myRoute",
url:"{language}/{node}/{action}/{tag}",
defaults:new { controller = "BlogHomePage", action = "Tags", tags = UrlParameter.Optional }
);

It would call type something like this into a browser

www.website.com/Tags/tag

It would call this controller, pre-populating the tags parameter.

public class BlogHomePageController : BasePageController<BlogHomePage>
{
public ActionResult Tags(string tags)
{
return View("Index");
}
}

The Problem

When you register your routes you have two options. One is the standard MVC MapRoute or use the Episerver extension MapContentRoute.

The one problem you get with using MVC routing is that you loose the EPiServer context. So, for example, if you create a custom route and register it via MVC routing and it redirects you to a controller, the current page object will not be populated and will only return null. This one stumped me for ages.. the breakpoint in my controller got hit but all my Episerver data was null.

If you’re in this situation, the easiest way to get the Episerver data back is to call it manually using the snippet below:

var pageRouteHelper = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance();
var currentPage= pageRouteHelper.Page;

In some circumstances this is fine and you may just want to do some simple filtering, in other cases you might need to use EPiServer Routing.

If you wanted to use a normal MVC page controller in your site, then using plain old fashioned MVC routing is the way to go

EPiServer Routing

Ok, so the first part of EPiServer routing is, from my understanding, that it needs to be called after the EPiServer context has been set-up.  This means you can’t really use the Global.asax.  Instead you need to create a InitializableModule. Below is a quick code example how this should look:

[InitializableModule]
[ModuleDependency(typeof(ServiceContainerInitialization))]
public class RouteConfig : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
RouteTable.Routes.MapContentRoute(
"EpiSeverRegisteredRoute", 
"{language}/{node}/{action}", 
new { action = "index" });
}
public void Uninitialize(InitializationEngine context) { }
public void Preload(string[] parameters) { }
}

When you use EPiServer routing, you do not use routes.MapRoute any more, instead you use the EPiServer methods, MapContentRoute and MapPageRoute.

When you use MapPageRoute you still use the same segments as you can in MVC like {node} and {language} as the segments don’t change. What it does is that by using the Episerver extensions they get populated correctly.

When you use MapContentRoute it can then make the Episerver segment work.  For reference these segment all inherit from EPiServer.Web.Routing.Segments.ISegment.

Conclusion

This should provide you with a basic introduction on how you can get routes up and working.

Useful References

If you’ve made it this far, here’s two pretty good Url’s you can use for reference:

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

More Posts

4 replies

Trackbacks & Pingbacks

  1. […] alternatives than you can find in this article.  For those people, I would recommend reading, EPiServer 7 Routing For Dummies. I understand how frustrating it is when you see snippets of code and you’re not quite sure […]

  2. […] previously blogged in EPiServer 7 Routing For Dummies which talked a bit about segments in EpiServer. Today we’re going to go one step further and […]

  3. […] previously blogged in EPiServer 7 Routing For Dummies which talked a bit about segments in EpiServer. Today we’re going to go one step further and […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

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