How To Get The MVC Controller Of An Episerver Block
I've previously written about a few requirements around donut caching and rendering custom content areas that involved needing to know the action and controller required for the current block. In How To Get The Action, Controller and Tag Data Out Of The Context In Episerver, but the next part of the puzzle is trying to get the action/controller for a block. I found the documentation around this a little sketchy at best, so I thought I'd write up the method I used to get what I needed.
I write this post with a warning, if you are reading this then you have probably architected something badly. In 99% of the cases you should never need this. For example, in my case I needed to create a custom cache key using a third party extension, the third part tool required me to set the action and controller name. I can only think of a few situations (mainly caching) where you would need to do something like this. If you are trying to get a form to work in a block.. this is not the way to go. In those scenarios, you may need to configure a custom route, or, another method I have used previously is to enable, like detailed here, Creating an Episerver Sign-Up Form.
In Episerver, blocks and block partials are rendered using the template resolver. The template resolver can be overridden and if you want to render your blocks with display options or without a controller, then this is something that you may look into (How To Make A Block Use Multiple Views? A Partial View Controller Explained). The code below is assuming you're either in a custom MVC Html helper, or you are overriding the ContentAreaRendere.
public static TemplateModel GetTemplateModel(HtmlHelper html, IContent content, string tag)
var contentTypeRepository= ServiceLocator.Current.GetInstance();
var templateResolver = ServiceLocator.Current.GetInstance();
var contentTypeRepository= typeRepo.Load(content.ContentTypeID);
var optionOne = templateResolver.Resolve(html.ViewContext.HttpContext, type, TemplateTypeCategories.Mvc);
var optionTwo= templateResolver.Resolve(html.ViewContext.HttpContext, type, TemplateTypeCategories.MvcPartial);
var recommendOption = templateResolver.ResolveMvcTemplate(html.ViewContext.HttpContext, type); return recommendOption;
The code uses two Episerver API's. The template resolver, this will figure out the controller name for a block for us and the content type repository. This API will get a blocks content type Id, look it up in the database and return the matching Episerver object. The first thing we do is get the content type from the content item being passed in, using the ContentTypeID property. The next thing is querying the template recover. In my snippet, I've included three ways that will all return the values you want. The best approach is to use ResolveMvcTemplate as it saves you specifying the template type category. From the object that's returned, you can then do recommendOption.Name to get the controller name!
Getting the controller name from a block is a bit of a faff and uses a few API'd that aren't really documented very well. The code to actually get the name is pretty simple and straightforward, we grab an instance of the block, pass it to the template resolver with the correct parameters and then use the Name property to get the controller name.