November Happy Hour will be moved to Thursday December 5th.
November Happy Hour will be moved to Thursday December 5th.
Routing in EPiServer is to content (what I mean is that during the routing step no attention is taken to how the content should be rendered). After routing is done (that is a content has been decided/found) a call is made to TemplateResolver which then selects which template that is most suitable to handle that content item (it can then return e.g. a WebForm, a MVC controller or a HttpHandler).
So what you probably want is not to hook into routing but instead hooki in to TemplateResolver and say that for this specific page I want to use this controller. Templates are registered per type but there is actually two events TemplateResolver.TemplateResolving and TemplateResolver.TemplateResolved where you can specify which template to use. In the eventargs you have the actual instance to render so there can you check if it is your "special" page and if so set your special controller to handle the request.
This is great, Johan. Exactly what I needed.
My only question is the phrase "set your special controller." I've looked through the SDK, all the samples, and your blog post, and I'm fuzzy on how to change the controller. It has something to do with SelectedTemplate, but I'm not sure what the correct syntax is for changing this.
Hey Deane, this should help, you can also use tags as well
[InitializableModule]
public class MobileRedirectSample : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
context.Locate.TemplateResolver().TemplateResolved += MobileRedirectSample_TemplateResolved;
}
public void Uninitialize(global::EPiServer.Framework.Initialization.InitializationEngine context)
{
}
private void MobileRedirectSample_TemplateResolved(object sender, TemplateResolverEventArgs eventArgs)
{
if (eventArgs.ItemToRender != null && eventArgs.ItemToRender is PageData &&
eventArgs.WebContext.Request.RequestContext.GetContentLink() == new ContentReference(459))
{
var specialTemplate = eventArgs.SupportedTemplates
.SingleOrDefault(r => r.Name.Contains("YourSpeacialPageController"));
if (specialTemplate != null)
{
eventArgs.SelectedTemplate = specialTemplate;
}
}
}
public void Preload(string[] parameters)
{
}
}
I saw this sample, but I'm not sure it's exactly what I need. This line seems to be the important line, but how do I get a controller into the "SupportedTemplates" collection?
var specialTemplate = eventArgs.SupportedTemplates
.SingleOrDefault(r => r.Name.Contains("YourSpeacialPageController"));
It is a very important line, What it does is since a page can have multiple templates, ie, starndard page, standard page with a tag, and so one, we are just specifing out of the supported templates which controller(template) we want this template to use.
So, since we have a page type called News, NewsPageController: PageController<NewsPage>, you can also have a controller like this as well, NewsListingPageController : PageController<NewsPage>. With that said, you can also have another controller with a templatedescriptor on it as well, since the page is oftype(NewsPage), this is how the supported templates are filled is based on their algorithm for finding the pages,
What is EPiServer MVC's capacity to route specifc pages through specific controllers? Not page types, but actual, single pages.
Say I have 1,000 articles in my system. I want all requests for those articles to be handled by ArticleController...except for Article #459. I want that one to go through SpecialArticleController. It's the same page type ("Article Page"), but I want it to just route that single page through a different controller.
Granted, this is a ridiculously contrived example, but here's what I'm trying to do --
Most sites generally have at least some application-ish functionality. These are pages which aren't content so much as little applications of some sort.
Now, in MVC, it's super easy to just hook up a new route, write a new controller, etc. The problem is that to render properly, a request usually has to be in the context of a page. For the master layout to work, for instance, it has to know where this page lies in the navigation, etc.
Stop now and read this -- this will all make more sense:
"Using Proxy Content Objects for Non-CMS Content"
http://gadgetopia.com/post/7088
So, my little application has to "represent" a page in the tree in order for it to render property. This being the case, I want to create a page "wrapper," but handle that page with its own controller. So all pages will go to Controller X, but this one will go to Controller Y.
Now, a way around this might be to write my application as a block, then just embed that in a page. This would work, but it seems odd to me. I don't like the idea that someone can delete or remove this block that's really foundational to the page. I don't like the idea of the main purpose of that page being so...temporal. (Maybe this is irrational...?)
So, my original question is how to route specific pages through specific controllers, but my larger question is: am I thinking through this correctly?