One of the biggest challenges I think a lot of developers struggle with is understanding the difference between MVC and Episerver.  I have heard untold conversations between developers blaming Episerver for doing something unwanted, when in the majority of situations, it's the individual's lack of knowledge of how MVC works and the difference between the two that's the main crux of the problem.

If you are new to MVC then I would recommend reading, Professional ASP.NET MVC 5 as it's a great introductory to MVC.

An MVC Page Request

All Episerver websites fundamentally run the same as any other .NET MVC website.  Underneath everything, the CLR still processes your code. IIS is still doing the same thing it would for any other MVC project and you use HTML, CSS, Javascript, Angular the same way.  

What Episerver provides is a framework that sits within this mesh of technologies that provide a huge array of functionality. Things start to get interesting when we look at the Global.asax.cs file.  If you have a peek inside, you should see that your website is inheriting from Episerver.Global.

This is the first sign that your Episerver site is not just a plain old vanilla MVC project.  In a normal MVC site, a user types in a URL.  If that Url matches a controller and action then your controller will be hit, any business logic will be run and a view is loaded.

When you work within the CMS, all your 'pages' live within a database.  Your pages/Url structure of your website does not match controllers and actions so the two concepts are very different.  As a piece of software, Episerver needs to bridge the gap between how MVC works and how to render the virtual pages that get created in the database.

In order to achieve this, Episerver hooks into the global.ascx file and adds in their own stuff.  This 'stuff' will involve things like defining a custom routing handler that will grab the URL request and then make a look-up in the database to see if any virtual pages might match the request.

If a virtual page exists, then Episerver needs to instantiate that page and return it back to the user.  This overview is quite simplistic as under the hood Episerver does a lot of other things, but this is one of the big concepts you need to understand when you work with a CMS.

This concept is easy to understand; we need a different way to do the routing because the web-pages live in a database, however, we still need the flexibility to build our websites like we would any normal MVC website. We still need a way to add our own business rules and logic, we still need to be able to decide what view and layout to use as well as hundreds of other things. Episerver can't simply just provide a CMS that lets content editor add some data into a few templates in a pre-set manner and then automatically wrap it all up and send it back out without passing it to the developers to tamper with first.

What we need is a way to process a request the same as we would a normal MVC site with all the Episerver data specific to that page request, so we can do whatever we want with.  This where we move away from the standard MVC page controller and introduce the Episerver PageController() and BlockController().

The Episerver Page Controller

When you look at a controller in any Episerver website, you will see it inherits from the Episerver PageController().  On a normal page request the Episerver routing intercepts the request, gets the all the data the content editors have added about that page, then in the PageController returns this data, as a 'CurrentPage' object.

In the snippet above, we have a standard MVC controller that will process any incoming requests for any page in the Episerver database that has been created as a ContentPage.  This is defined by the PageController bit. The ContentPage is a custom class that we have defined in code. A basic implementation of the content page could look like this:

The Content Page Controllers Index method will then get triggered when someone visits your website, types in a URL that matches a page that exists in the Episerver database.  

Episerver will then populate the Content Page Types properties and then return it back into the MVC pipeline.  MVC will then look for a controller that is set to deal with ContentPages and then triggers that controller. The currentPage parameter in the Index method will be populated automatically with data.  In this example, say a content editor creates a 'ContentPage' called 'ContactUs' in the Episerver editor under the home page and set the URL of the page as 'ContactUs'.  

The content editor then sets the DummyText property defined in the ContentPage class with the data 'Oranges'. Someone visits your website and types in the Url IIS will forward the request to your web application.  

Episerver will intercept the request, talk to the database and find out that there is indeed a page in Episerver that matches the request.  Episerver will then create a new instance of the ContentPage class and will populate all of its properties. Episerver will then find the controller that we have defined to process ContentPage so that the controller will get called, in this case, the ContentPageController.  

The Index method by default will be called and the ContentPage object Episerver has populated will be passed in as the currentPage parameter in the index method. From this point the process works exactly the same as any other MVC site, we can call our business layer, we can create view models and we can call our views. We have all the page data so we can then render it however we want.