When working with Episerver, you get very used to rendering pages and blocks, however, if you want to render a normal MVC controller, life can be a little more difficult without the right know-how.
Before we go into the code, we need to talk about routing. If you want to access a normal controller within an Episerver site, you need to configure a custom route in your route table. This step is slightly different from a normal C# MVC website. In a bog standard MVC site, the sites Url structure usually maps directly to the controllers and actions defined, e.g. www.website.com/home would map a controller called home. Within the Episerver world, this routing structure won't work. In Episerver you have virtual pages whose Url structure is dependent on how the pages are created within the editor. An action within Episerver won't map directly to an Url.
Any Episerver page type needs different routing to normal MVC routing to cater for this mismatch. Although each page type will have its own controller. The Url that will Although each page type will have its own controller, Url's that will point to that controller will be completely different. This is one of the big areas why Episerver routing and MVC routing are so 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 set-up an Episerver site via Nuget, a custom Episerver route is included that maps an incoming Url request to point to the correct Episerver page controller.
I won't go into the details but just trust that it happens. This means that if you want to start working with a normal controller, the first thing we need to do to register a route that maps a URL to the controller you want to trigger. Think aobut it this way, 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 would look like this:
In the code above, I'm creating a Route definition with a name called 'DebuggingInformation'. This identifier can be anything you like as it's an internal name only which means it's never used in the front-end. The name is unimportant and can be anything. The second part of the route definition defines the Url that will trigger the controller to be called. In this example, the Url www.website.com/DebuggingInformation will match the controller name.
The last part maps to the action within the controller. action and index to use. In this case, we will create a controller called MetaDataController (notice how you don't need to use the Controller part in the route) with a default Index action.
The next step is to write the controller code.
The controller inherits form 'Controller' we don't use any Pages or Block at all :) In case you still want to get access to Episerver data you can use the PageRouteHelper to get information.
The page will get information about the start page. (If you are wondering why we would need this in a non-Episerver page, then in my next guide I'll show you how you can create custom views into to a pluggable area) After we do all the processing we need, we can then render a view as normal.
Lastly, we create a MetaData folder in underneath the view folder and create a Razor page called index.cshtml. Within the view I'm using the following mark-up:
One thing that can trip you up is if you try to use your default master layout in your normal MVC views. If you try to load your Episerver master layout, that's been written to except an Episerver page then it's likely you'll see an exception when you try to load your page. In theory, you can use any layout you want, but, in practice, if you try and use your existing Episerver master layout, in a normal MVC context in 99% of the cases your code will fail. The reason for this is that when you work with Episerver routing, thin like Ek the Episerver Current Page property will be automatically populated with data, based on the current page request for you.
The API expect certain bits of data to be populated to do this. When this data doesn't exist, your Epi code will throw exceptions because the HTTP Context will be missing key bits of data that it expects to populate these behind the scenes aspects. This might mean you need to create two seperate headers for example, one for Episerver and one for your non-Episerver pages.
In today's lesson, we've covered how to use 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 making sure you override the Layout property so the main sites header and footer doesn't load.
All the above code can be downloaded in a fully working website from my github account here. #ILoveEpiserver