In this tutorial, you will learn how to use a vanilla MVC controller when working with Episerver CMS. When creating controllers with Episerver, life is easy. using either
BlockController all the routing is handled for you. If you want to work with non-Episerver related requests in your application, you will need to use a normal MVC controller. When using a vanilla controller, things can become a little more difficult, mainly because of routing
In a bog standard ASP.NET MVC website, the site Url structure usually maps directly to the controllers and actions defined. For example, this URL
www.website.com/order would map a controller called
OrderController and an action method called
Index. When working within a CMS, this URL to controller map will not work. In Episerver, content editors create virtual pages within the editor., The Url structure of those pages will be based on where they are created in the page tree. A request within Episerver won't simple map to controller/action. It will be based on data held within the Episerver database.
This is why Episerver page requests require different routing rules compared to normal MVC routing, to cater for this mismatch. Each page type you define will also require you to build a corresponding controller. That controller will not be responsible for only rendering a single page, it will need to cater for all pages that have been created within the CMS using that page type. This magic happens as the current page object will also be passed into the controller. When a page request occurs, Episerver will do a database lookup based on the URL, if a match is found it will get the page data from the CMS, add it to the request and then within the controller, you can then access that page data. Routing is one of the big areas where Episerver and vanilla MVC are very different. MVC maps a single Url to a controller (roughly) and many Episerver URLs can point to the same controller 🔥🔥🔥
Behind the scenes, a different type of routing is used with Episerver. When you install Episerver in an application, the default routing rule is change with a custom Episerver rule. This rule defines different segmenting rules on a Uel. I won't go into the details but just trust that it happens (read this for more information).
If you want to start working with a vanilla controller, you need to enable the default MVC routing rule again. The rule needs to map the URL to the controller you want to trigger. In essence, Episerver takes out the default MVC routing and if you want to work with normal MVC routing, you need to manually add it back in! The code to add a normal MVC route looks like this:
In the code above, I'm creating a new routing rule named
DebuggingInformation. This identifier can be anything you like as it's an internal name that is only used in the front-end. The second part of the route definition defines that maps the segments within a Url to a controller and an action. In this example, the Url
www.website.com/DebuggingInformation will match the controller named
DebuggingInformationController. The last part maps to the action within the controller. The default action name is
index. This is why you need to create a method called
Index within your controller.
The next step is to write the controller code. We will create a controller called
MetaDataController (notice how you need to use the Controller part) this is a default convention you need to follow:
The controller inherits from the normal MVC
Controller not the Episerver one. In case you still want to get access to Episerver data in your vanilla controller, you can use the
PageRouteHelper to get information. After we do all the processing we need, we can then render a view as normal.
Lastly, we create a view. In the view folder, create a folder called
MetaData underneath the view folder. Create a new view called
index.cshtml. In my example I'm using the following mark-up:
One thing that can trip you up is around masters layouts. If you use
inherits in your master layout, that types your master view to an Episerver page object. When the request tries to load the layout, the current page object will not exist and an exception will be thrown. Typing your master layout to an Episerver object is useful as it will give you access to the current page name within the layout. This is handy for rendering the
head section on a page.
If you follow this pattern and data doesn't exist, your Epi code will throw exceptions because the
HTTPContext will be missing key bits of data. One solution is to create a new layout for non-episerver related requests. My preferred is to never type the master layout file and avoid the issue!
You now know how to create a normal page controller in Episerver. First, you need to define a route that will point to your controller and action. Next, you create a controller that inherits from 'Controller', lastly you create a view. Remember, do not use a layout that
inherits from an episerver page
All the above codes can be downloaded from my Github account here. Happy Coding 🤘