In this tutorial, you will learn about how URL segments work in Episerver and how you can create your own custom segment handler. This handler can be registered on Episerver start-up to apply custom routing rules. If you are new to Episerver routing, I suggest you read Episerver 7 Routing For Dummies first. Today, we are going to go one step further than the tips in that tutorial by creating our own custom segment. If you need to do some crazy routing in Episerver, this one is for you 🔥🔥🔥
What Is A URL Segment?
When websites were built using HTML files, a web page Url structure was comprised of the sites folder structure and the files in those folders. A URL mapped to a file on a server, simples. With MVC we have controllers and actions. In a vanilla non-CMS MVC website, a Url
maps to the controller class and action. The name of the first segment in the URL will be the controller name. If the action is not using the default value of Index
, the action will be the second segment in the URL.
In the example above, search
is the first segment and about
is the second segment. To make this request work a controller called SearchController
with an action called About()
would need to exist within the application. In an MVC application, this mapping of URL to code is done via the default MVC routing rule. This default rule looks like this:
The default MVC routing rule defines two segments {controller}
and {action}
. The rule will map the URL to some code. When we add a CMS into an MVC application, the CMS needs to change how this default rule works. Below shows the default Episerver routing rule:
In a CMS, the website URL hierarchy is built from virtual pages within a database. In Episerver we need to map a request to a page that has been built using a certain page type. This is why in the Episerver routing rule we have the {node}
segment. {node}
will contain an Episerver content reference that maps to this virtual page. {node}
is the segment that makes the CurrentPage
magic in a controller work. The Episerver rule also contains a {language}
segment. Episerver can be configured to work in multi-language mode and {language}
is the name of the segment that deals with it.
To recap, in MVC you can create your own routing rules. Segments are used within these rules as the identifiers to trigger a match 💥
You might be asking, why would I need to create a custom segment? The most common scenario is to help your site SEO by making complex URLs more user friendly. In the old world let's say you had a search page that you used a query string to pass in the search term. Let us take this common example:
With MVC, we can change the routing rule to allow for a more user friendly URL that still triggers the same code:
There are loads of variations of this scenario, tagging, categories, news, pagination, etc...
Creating A Custom Segment
To allow for this new type of URL pattern, we define a custom segment. The segment will just work for the search page. The search term parameter will be mapped to the URL and the search term will automatically pass into a controller as a parameter:
To create a custom segment, we need to create a new class and either inherit from SegmentBase
or ParameterSegment
. When you inherit from SegmentBase
you have to implement GetVirtualPathSegment
and RouteDataMatch
. Implementing from ParameterSegment
means you only have to implement GetVirtualPathSegment
:
In GetVirtualPathSegment
, you need to check that the current page request is of type SearchPage
. If it does, we need to populate a segment called searchterm
with the search term. With this rule defined, you can add a parameter to your controller called searchterm
and it will automatically be populated when called. The value of the segment will be populated by the last segment in the URL:
In our code, the first thing we do is get the actual segment value itself:
This should return us the text searchterm
in our example. The next bit will assign the segment value into a custom segment.
In this method, we're using the Episerver API to check if the current page is of type SearchPage
. If it is, set the current segment in RouteData
and assign it to [Name]
. If the page isn't a search page we carry on and process the URL as normal.
Registering The Segment
The last part of the puzzle is actually registering our customer segment. This is done in the global.ascx
file. If we don't set the segment rule correctly, you will get a 404-page error in testing. 404 occur when the route handler doesn't know how to translate the Url. I should warn you it can be a bit of a pain to debug this when you set it up wrong 😔.If you get a 404, check the rule. A match needs to be made on the controller and action segments first, so the custom search term can be segmented:
When we use MVC routing we need a way to map the URL to a controller, action method and additional properties. This is really useful for SEO friendly Url's. Instead of using query string values, we can add the old query string values directly into the Url if we want to. To add this type of feature we need to create a custom segment.
All the above code can be downloaded to a fully working website from my GitHub here. Happy Coding 🤘