Using Umbraco Route Hijacking and posting to it
Simple usage of Umbraco route hijacking allows you to add more features to your website and respond to your viewers request in a better way. It will also allow you to use custom models and populate them before the view gets called/rendered.
To start with route hyjacking you need to create a document type for your page, the name of the document type is important because your controller will need to have the same name as the document type in order for the Umbraco routing engine to pick it up.
Tip: Say we create a document type called NewsLister, we would need to create a controller called NewsListerController within a class file called anything, I'll call mine, NewsListerController.cs.
Now you need to create a template that the document type will allow, I'll also call my template NewsLister.
Tip: The name of the template only matters if you're planning on handling multiple templates from one controller.
Assign your template to the document type and create a page in the content area that used your new document type and template.
Now, in NewsListerController.cs, add the following code:
public class NewsListerController : RenderMvcController { // The default action to render the front-end view, will populate the model and return the view. public override ActionResult Index(RenderModel objModel) { // Construct a new model to work with. MyModel objModel = new MyModel() { MyVariable = "Some value." }; // Return the search results view with the populated model. (The template dropdown becomes irrelevent in a hybrid controller.) return CurrentTemplate(objModel); } }
Now all you need to do is make sure that your template has the following at the top of the file:
@inherits Umbraco.Web.Mvc.UmbracoViewPage
The index method is called if a method does not exist with the same name as the template used, so to do something else with a different template, just add another method witht hat templates name and add some similar code.
Tip: Replace MyModel with the name of the class that will contain the data you need to use in your page.
See the following code as an example of a model you could use.
// Minimal routing model, contains a parameterless constructor so that it can be used for postbacks. public class MyModel : RenderModel { // Parameterless constructor to handle postbacks, will call the main constructor. public MyModel() : this(UmbracoContext.Current.PublishedContentRequest.PublishedContent) { } // Main constructor. public MyModel(IPublishedContent content) : base(content) { } public String MyVariable { get; set; } }
That's it!
You might run into an issue some people get where you want to post to the page that's been rendered via a route hijack, but the controller is of type RenderMvcController and not SurfaceController. Don't worry I've got you covered, add the following class to your website somewhere and extend your controller with it instead of the RenderMvcController, as it implements both SurfaceController and RenderMvcController, you will be able to use route hijacking on and post a form to the same controller, pretty neat eh?
// The base route controller allows the use of a surface controller and a rendermvc controller in one. // This allows us to create a controller that can be used for both route hyjacking and and form posting. public class BaseRouteController : SurfaceController, IRenderMvcController { // The default action to render the front-end view. public virtual ActionResult Index(RenderModel model) { // Just return the chosen template from the back office. return CurrentTemplate(model); } // Checks to make sure the physical view file exists on disk. protected bool EnsurePhysicalViewExists(string template) { var result = ViewEngines.Engines.FindView(ControllerContext, template, null); if (result.View == null) { LogHelper.Warn("No physical template file was found for template " + template); return false; } return true; } // Returns an ActionResult based on the template name found in the route values and the given model. // If the template found in the route values doesn't physically exist, then an empty ContentResult will be returned. protected ActionResult CurrentTemplate(T model) { var template = ControllerContext.RouteData.Values["action"].ToString(); if (!EnsurePhysicalViewExists(template)) { return Content(""); } return View(template, model); } }
See more on this, here: https://our.umbraco.org/documentation/reference/routing/custom-controllers
Published at 11 Feb 2016, 13:38 PM
Tags: Umbraco