Umbraco CMS
CloudHeartcoreDXPMarketplace
10.latest (LTS)
10.latest (LTS)
  • Umbraco CMS Documentation
  • Legacy Documentation
    • Umbraco 11 Documentation
    • Umbraco 8 Documentation
    • Umbraco 7 Documentation
  • Release Notes
  • Contribute
  • Sustainability Best Practices
  • Fundamentals
    • Get to know Umbraco
    • Setup
      • Requirements
      • Installation
        • Install using .NET CLI
        • Install using Visual Studio
        • Local IIS With Umbraco
        • Install Umbraco With Visual Studio Code
        • Installing Nightly Builds
        • Running Umbraco On Linux/macOS
        • Unattended Installs
      • Upgrade your project
        • Version Specific Upgrades
          • Upgrade from Umbraco 8 to Umbraco 10
          • Migrate content to Umbraco 8
          • Minor upgrades for Umbraco 8
          • Upgrade to Umbraco 7
          • Minor upgrades for Umbraco 7
      • Server setup
        • Running Umbraco On Azure Web Apps
        • Hosting Umbraco in IIS
        • File And Folder Permissions
        • Runtime Modes
        • Running Umbraco in Docker
        • Umbraco in Load Balanced Environments
          • Load Balancing Azure Web Apps
          • Standalone File System
          • Advanced Techniques With Flexible Load Balancing
          • Logging With Load Balancing
    • Backoffice
      • Sections
      • Property Editors
        • Built-in Property Editors
          • Checkbox List
          • Color Picker
          • Content Picker
          • DateTime
          • Date
          • Decimal
          • Email Address
          • Eye Dropper Color Picker
          • File Upload
          • Image Cropper
          • Label
          • List View
          • Markdown Editor
          • Media Picker
          • Media Picker (Legacy)
          • Member Group Picker
          • Member Picker
          • Multi Url Picker
          • Multinode Treepicker
          • Repeatable Textstrings
          • Nested Content (Legacy)
          • Numeric
          • Radiobutton List
          • Slider
          • Tags
          • Textarea
          • Textbox
          • Toggle
          • User Picker
          • Block Editors
            • Block Grid
            • Block List
            • Build a Custom View for a Block
            • Configuring Block Editor Label Properties
          • Dropdown
          • Grid Layout (Legacy)
            • What Are Grid Layouts?
            • Configuring The Grid Layout
            • Settings And Styling
            • Grid Editors
            • Build Your Own Editor
            • Rendering Grid In a Template
            • Grid Layout Best Practices
            • Add Values Programmatically
          • Rich Text Editor
            • Rich Text Editor Configuration
            • Rich Text Editor Styles
      • Login
      • Content Templates
      • Infinite Editing
      • Log Viewer
      • Language Variants
      • Settings Dashboards
    • Data
      • Defining Content
        • Default Document Types
      • Creating Media
        • Default Data/Media Types
      • Members
      • Data Types
        • Default Data Types
      • Scheduled Publishing
      • Using Tabs
      • Users
      • Relations
      • Dictionary Items
      • Content Version Cleanup
    • Design
      • Templates
        • Basic Razor Syntax
        • Named Sections
        • Razor Cheatsheet
      • Rendering Content
      • Rendering Media
      • Partial Views
      • Partial View Macro Files
      • Stylesheets And JavaScript
    • Code
      • Service APIs
      • Subscribing To Notifications
      • Creating Forms
      • Debugging
        • Logging
      • Source Control
  • Implementation
    • Learn how Umbraco works
    • Routing
      • Controller & Action Selection
      • Execute Request
      • Request Pipeline
    • Custom Routing
      • Adding a hub with SignalR and Umbraco
    • Controllers
    • Data Persistence (CRUD)
    • Composing
    • Integration Testing
    • Nullable Reference Types
    • Services and Helpers
      • Circular Dependencies
    • Unit Testing
  • Extending
    • Customize the editing experience
    • Dashboards
    • Sections & Trees
      • Sections
      • Trees
        • Tree Actions
      • Searchable Trees (ISearchableTree)
    • Property Editors
      • Package Manifest
      • Property Value Converters
      • Property Actions
      • Tracking References
      • Declaring your property editor
      • Content Picker Value Converter Example
    • Macro Parameter Editors
    • Health Check
      • Health Check Guides
        • Click-Jacking Protection
        • Content/MIME Sniffing Protection
        • Cross-site scripting Protection (X-XSS-Protection header)
        • Debug Compilation Mode
        • Excessive Headers
        • Fixed Application Url
        • Folder & File Permissions
        • HTTPS Configuration
        • Macro Errors
        • Notification Email Settings
        • SMTP
        • Strict-Transport-Security Header
    • Language Files & Localization
    • Backoffice Search
    • Backoffice Tours
    • Backoffice UI API Documentation
    • Content Apps
    • Creating a Custom Database Table
    • Embedded Media Providers
    • Custom File Systems (IFileSystem)
      • Using Azure Blob Storage for Media and ImageSharp Cache
    • Configuring Azure Key Vault
    • Packages
      • Package Types
      • Creating a Package
      • Language file for packages
      • Listing a Package on the Umbraco Marketplace
      • Good practice and defaults
      • Packages on Umbraco Cloud
      • Installing and Uninstalling Packages
      • Maintaining packages
      • Create accessible Umbraco packages
      • Example Package Repository
    • UI Library
  • Reference
    • Dive into the code
    • Configuration
      • Basic Authentication Settings
      • Connection strings settings
      • Content Dashboard Settings
      • Content Settings
      • Data Types Settings
      • Debug settings
      • Examine settings
      • Exception filter settings
      • FileSystemProviders Configuration
      • Global Settings
      • Health checks
      • Hosting settings
      • Imaging settings
      • Indexing settings
      • Install Default Data Settings
      • Keep alive settings
      • Logging settings
      • Maximum Upload Size Settings
      • Models builder settings
      • NuCache Settings
      • Package Migration
      • Plugins settings
      • Request handler settings
      • Rich text editor settings
      • Runtime minification settings
      • Runtime settings
      • Security Settings
      • Serilog settings
      • Tours settings
      • Type finder settings
      • Unattended
      • Web routing
    • Templating
      • Macros
        • Managing macros
        • Partial View Macros
      • Models Builder
        • Introduction
        • Configuration
        • Builder Modes
        • Understand and Extend
        • Using Interfaces
        • Tips and Tricks
      • Working with MVC
        • Working with MVC Views in Umbraco
        • View/Razor Examples
        • Using MVC Partial Views in Umbraco
        • Using View Components in Umbraco
        • Querying & Traversal
        • Creating Forms
    • Querying & Models
      • IMemberManager
      • IPublishedContentQuery
      • ITagQuery
      • UDI Identifiers
      • UmbracoContext helper
      • UmbracoHelper
      • IPublishedContent
        • IPublishedContent Collections
        • IPublishedContent IsHelpers
        • IPublishedContent Property Access & Extension Methods
    • Routing & Controllers
      • Routing requirements for backoffice authentication
      • Custom MVC controllers (Umbraco Route Hijacking)
      • Custom MVC Routes
      • URL Rewrites in Umbraco
      • Special Property Type aliases for routing
      • URL Redirect Management
      • Routing in Umbraco
        • FindPublishedContentAndTemplate()
        • IContentFinder
        • Inbound request pipeline
        • Outbound request pipeline
        • Published Content Request Preparation
      • Surface controllers
        • Surface controller actions
      • Umbraco API Controllers
        • Umbraco Api - Authorization
        • Umbraco Api - Routing & Urls
    • Searching
      • Examine
        • Examine Management
        • Examine Manager
        • Custom indexing
        • PDF indexes and multisearchers
        • quick-start
    • Using Notifications
      • Notification Handler
      • CacheRefresher Notifications Example
      • ContentService Notifications Example
      • Creating And Publishing Notifications
      • Determining if an entity is new
      • MediaService Notifications Example
      • MemberService Notifications Example
      • Sending Allowed Children Notification
      • Umbraco Application Lifetime Notifications
      • EditorModel Notifications
        • Customizing the "Links" box
    • Inversion of Control / Dependency injection
    • Management
      • Models Reference
        • Content
        • ContentType
        • DataType
        • DictionaryItem
        • Language
        • Media
        • MediaType
        • Relation
        • RelationType
        • ServerRegistration
        • Template
      • Services Reference
        • AuditService
        • ConsentService
        • DataTypeService
        • DomainService
        • EntityService
        • ExternalLoginService
        • FileService
        • MacroService
        • MediaService
        • MemberGroupService
        • MemberService
        • MemberTypeService
        • NotificationService
        • PackagingService
        • PublicAccessService
        • RedirectUrlService
        • RelationService
        • ServerRegistrationService
        • TagService
        • TextService
        • ContentService
          • Create content programmatically
        • ContentTypeService
          • Retrieving content types
          • Retrieving content types
        • LocalizationService
          • Retrieving languages
        • UserService
          • Creating a user
    • Plugins
      • Creating Resolvers
      • Finding types
    • Cache & Distributed Cache
      • Accessing the cache
      • ICacheRefresher
      • IServerMessenger
      • Getting/Adding/Updating/Inserting Into Cache
      • Examples
        • Working with caching
    • Response Caching
    • Security
      • Linking External Login Provider accounts
      • BackOfficeUserManager and Events
      • Cookies
      • Replacing the basic username/password check
      • External login providers
      • Locking of Users and password reset
      • Reset admin password
      • Umbraco Security Hardening
      • Umbraco Security Settings
      • Sensitive data
      • Sanitizing the Rich Text Editor
      • Setup Umbraco for a FIPS Compliant Server
      • HTTPS
      • Two-factor Authentication
      • Server-side file validation
    • Scheduling
    • Common Pitfalls & Anti-Patterns
    • API Documentation
    • Debugging with SourceLink
    • Language Variation
    • UmbracoMapper
    • Distributed Locks
    • AngularJS
      • Directives
        • umbLayoutSelector
        • umbLoadIndicator
        • umbProperty
      • Services
        • Editor Service
        • Events Service
          • changeTitle
  • Tutorials
    • Overview
    • Creating a Basic Website
      • Getting Started
      • Document Types
      • Creating Your First Template
      • CSS and Images
      • Displaying the Document Type Properties
      • Creating a Master Template
      • Creating Pages and Using the Master Template
      • Setting the Navigation Menu
      • Articles and Article Items
      • Adding Language Variants
      • Conclusions
    • Creating a Custom Dashboard
    • Creating a Property Editor
      • Adding configuration to a property editor
      • Integrating services with a property editor
      • Adding server-side data to a property editor
    • Creating a Multilingual Site
    • Add Google Authentication
    • Add Microsoft Entra ID authentication (Members)
    • The Starter Kit
      • Lessons
        • Customize the Starter Kit
        • Add a Blog Post Publication Date
          • Add a Blog Post Publication Date
          • Add a Blog Post Publication Date
        • Add Open Graph
          • Add Open Graph - Step 1
          • Add Open Graph - Step 2
          • Add Open Graph - Step 3
          • Add Open Graph - Step 4
          • Add Open Graph - Summary
        • Ask For Help and Join the Community
    • Editor's Manual
      • Getting Started
        • Logging In and Out
        • Umbraco Interface
        • Creating, Saving and Publishing Content Options
        • Finding Content
        • Editing Existing Content
        • Sorting Pages
        • Moving a Page
        • Copying a Page
        • Deleting and Restoring Pages
      • Working with Rich Text Editor
      • Version Management
        • Comparing Versions
        • Rollback to a Previous Version
      • Media Management
        • Working with Folders
        • Working with Media Types
        • Cropping Images
      • Tips & Tricks
        • Refreshing the Tree View
        • Audit Trail
        • Notifications
        • Preview Pane Responsive View
        • Session Timeout
    • Multisite Setup
    • Member Registration and Login
    • Custom Views for Block List
    • Connecting Umbraco Forms and Zapier
    • Creating an XML Sitemap
    • Implementing Custom Error Pages
Powered by GitBook
On this page
  • What is Umbraco Route Hijacking?
  • Creating a custom controller
  • Example: Hijacking route requests to a 'product' page
  • Routing via template
  • Example: Hijacking route requests to a 'product' for an alternative 'AMP' template
  • Summary - How the route hijacking convention works
  • Returning a view with a custom model
  • Changing the @inherits directive of your template
  • Processing QueryString values in the controller
  • Controller Injection
  • Replace Umbraco's default RenderController
Edit on GitHub
Export as PDF
  1. Reference
  2. Routing & Controllers

Custom MVC controllers (Umbraco Route Hijacking)

Use a custom MVC controller to handle and control incoming requests for content pages based on a specific Document Type, also called Route Hijacking.

Use a custom controller to handle and control incoming requests for content pages based on a specific Document Type

What is Umbraco Route Hijacking?

By default, all front end requests to an Umbraco site are auto-routed via the 'Index' action of a core Controller: Umbraco.Cms.Web.Common.Controllers.RenderController. This core controller handles the incoming request, builds the associated PublishedContent model, and passes this to the appropriate Umbraco Template/MVC View.

It is however possible to implement a custom Controller to replace this default implementation to give complete control over this execution.

For example:

  • To enrich the view model passed to the template with additional properties (from other published content items or outside Umbraco)

  • To implement serverside paging

  • To implement any custom/granular security

  • To return alternative templates depending on some custom business logic

This replacement of the default controller can be made 'globally' for all requests (see last example). It can also be by 'hijacking' requests for types of pages based on their specific Document Type following this controller naming convention: [DocumentTypeAlias]Controller.

Creating a custom controller

Example: Hijacking route requests to a 'product' page

In the following example, imagine an Umbraco site with a set of 'product' pages created from a Document Type called 'Product Page' with an alias 'productPage'.

Create a custom locally declared controller in the Umbraco web application project named 'ProductPageController'.

Ensure that this controller inherits from the base controller Umbraco.Cms.Web.Common.Controllers.RenderController.

eg:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Web.Common.Controllers;

namespace My.Website
{
    public class ProductPageController : RenderController
    {
        public ProductPageController(ILogger<ProductPageController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor)
            : base(logger, compositeViewEngine, umbracoContextAccessor)
        {
        }

        public override IActionResult Index()
        {
            // you are in control here!

            // return a 'model' to the selected template/view for this page.
            return CurrentTemplate(CurrentPage);
        }
    }
}

All requests to any 'product' pages in the site will be'hijacked' and routed through the custom ProductPageController.

If you prefer to use an async controller your need to override both the sync and the async Index()-methods. This is done to disable the default behavior from the base controller.

public class ProductPageController : RenderController
{
       
    [NonAction]
    public sealed override IActionResult Index() => throw new NotImplementedException();
    public async Task<IActionResult> Index(CancellationToken cancellationToken)
    {
        await SomethingAsync(cancellationToken);
        return CurrentTemplate(CurrentPage);
    }
}

This example shows the default behaviour that Umbraco's core RenderController provides. The 'Index' action of the controller is executed, and the CurrentTemplate helper sends the model containing the details of the published content item related to the request to the relevant template/view.

Routing via template

A further convention is that if an action on the controller has a name that matches the template name, this action will be executed instead of the default 'Index' action.

Example: Hijacking route requests to a 'product' for an alternative 'AMP' template

In this example, the Product Page Document Type has two templates 'ProductPage' and 'ProductAmpPage'. We can hijack and handle the requests to the two templates differently.

Create the Controller as before:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Web.Common.Controllers;


namespace My.Website
{
    public class ProductPageController : RenderController
    {
        public ProductPageController(ILogger<ProductPageController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor)
            : base(logger, compositeViewEngine, umbracoContextAccessor)
        {
        }

        // Any request for the 'ProductAmpPage' template will be handled by this Action
        public IActionResult ProductAmpPage()
        {
            // Create AMP specific content here...
            return CurrentTemplate(CurrentPage);
        }

        public override IActionResult Index()
        {
            // you are in control here!

            // return a 'model' to the selected template/view for this page.
            return CurrentTemplate(CurrentPage);
        }
    }
}

How can a page be requested via two different templates?

The page in Umbraco will have a single 'template' selected as it's default template, but it's possible to call this same page on a different template by adding ?altTemplate=othertemplatename to the Url QueryString eg:

/products/superfancyproduct/?altTemplate=ProductAmpPage

Summary - How the route hijacking convention works

  • Document Type name = controller name

  • Template name = action name (if no action matches or is not specified - then the 'Index' action will be executed).

  • Controller Inherits from Umbraco.Cms.Web.Common.Controllers.RenderController

Returning a view with a custom model

The steps to achieve this will differ, depending if your template views are using IPublishedContent or Modelsbuilder generated Models.

Changing the @inherits directive of your template

By default, your Umbraco Template will be based on the ContentModel that the default RenderController passes through to it.

The default inherits statement:

@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage

or if you are using modelsbuilder:

@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ProductPage>

<> contains a model generated for each document type to give strongly typed access to the Document Type properties in the template view.

To use a specific custom view model, the @inherits directive will need to be updated to reference your custom model using the Umbraco.Cms.Web.Common.Views.UmbracoViewPage<T> format where 'T' is the type of your custom model.

So for example, if your custom model is of type 'MyProductViewModel' then your @inherits directive will look like:

@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<MyProductViewModel>

Views will likely specify a master view to use as the common layout for the site html. When using a custom view model it's necessary to make sure this doesn't conflict with any implementation in the master layout view. Eg. if your master layout view is inheriting from a specific model UmbracoViewPage<SpecificModel> and using a property from SpecificModel that isn't available in your custom model an exception will be thrown. To avoid this you could:

  • Keep your Master layout view 'generically typed', eg. only have @inherits UmbracoViewPage, and use Model.Value syntax to access properties. or

  • Break the dependency on Umbraco.Cms.Core.Models in your master layout by having it instead inherit from Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ISomeInterface>. This would be where ISomeInterface is implemented by all your models and contains the properties that the master layout view uses. or

  • Ensure your custom models inherit from whichever class is used to strongly type the master layout view.

In most cases you will need your custom model to build upon the underlying existing PublishedContent model for the page. This can be achieved by making your custom model inherit from a special base class called PublishedContentWrapped:

public class MyProductViewModel : PublishedContentWrapped
{
    // The PublishedContentWrapped accepts an IPublishedContent item as a constructor
    public MyProductViewModel(IPublishedContent content, IPublishedValueFallback publishedValueFallback) : base(content, publishedValueFallback)
    {
    }

    // Custom properties here...
    public int StockLevel { get; set; }
    public IEnumerable<Distributor> ProductDistributors { get; set; }
}

PublishedContentWrapped will take care of populating all the usual underlying Umbraco properties and means the @Model. syntax will continue to work in the layouts used by your template.

Using Modelsbuilder you will find that all the generated models have a constructor that takes an IPublishedContent item in a similar way:

public class MyProductViewModel : ProductPage
{
    // The ProductPage model accepts an IPublishedContent item as a constructor
    public MyProductViewModel(IPublishedContent content, IPublishedValueFallback publishedValueFallback) : base(content, publishedValueFallback)
    {
    }

    // Custom properties here...
    public int StockLevel { get; set; }
    public IEnumerable<Distributor> ProductDistributors { get; set; }
}

The models generated by Modelsbuilder are created as partial classes so it's possible to extend them by adding your own partial classes with matching signature.

We can now populate our custom view model in our controller and use the values from the custom model in our template view:

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Web.Common.Controllers;
using My.Website.Models;


namespace My.Website
{
    public class ProductPageController : RenderController
    {
        private readonly IVariationContextAccessor _variationContextAccessor;
        private readonly ServiceContext _serviceContext;
        public ProductPageController(ILogger<ProductPageController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor, IVariationContextAccessor variationContextAccessor, ServiceContext context)
            : base(logger, compositeViewEngine, umbracoContextAccessor)
        {
            _variationContextAccessor = variationContextAccessor;
            _serviceContext = context;
        }

        public override IActionResult Index()
        {

            // you are in control here!
            // create our ViewModel based on the PublishedContent of the current request:
            // set our custom properties
            var productViewModel = new MyProductViewModel(CurrentPage, new PublishedValueFallback(_serviceContext, _variationContextAccessor))
            {
                StockLevel = 4, 
                ProductDistributors = new List<Distributor>()
            };

            
            // return our custom ViewModel
            return CurrentTemplate(productViewModel);

        }
    }

}

and in our template

@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<MyProductViewModel>
@{
Layout = "Master";
}
<h1>@Model.Name</h1>

@(Model.Value<IHtmlString>("productDescription"))
// or using Modelsbuilder
@Model.ProductDescription

<dl>
<dt>Stock Level</dt>
<dd>@Model.StockLevel</dd>
<dt>Distributors</dt>
@foreach (var distributor in Model.Distributors){
<dd>@distributor.Name</dd>
}

Processing QueryString values in the controller

You can also pass values directly into the controller action using the query string.

?page=1&andanotherthing=umbraco

The values in the querystring will be bound to the matching parameters defined in the controller's action:

public class ProductListingPageController : Umbraco.Cms.Web.Common.Controllers.RenderController
{
   //notice how we are no longer overriding the Index action because the signature is now different to the base signature.
    [HttpGet]
    public IActionResult Index([FromQuery(Name = "page")] int page, [FromQuery(Name = "andAnotherThing")] string andAnotherThing)
    {
       var products = _madeUpProductService.GetProductsByPage(page);
       var productListingViewModel = new ProductListingViewModel(CurrentPage, new PublishedValueFallback(_serviceContext, _variationContextAccessor));
       productListingViewModel.Products = products;
       productListViewModel.Thing = andAnotherThing;

       return CurrentTemplate(productListViewModel);
    }
}

Controller Injection

For example:

    public class ProductListingPageController : RenderController
    {
    private readonly IMadeUpProductService _madeUpProductService;
    public ProductListingPageController(ILogger<RenderController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor, IMadeUpProductService madeUpProductService)
    {
        _madeUpProductService = madeUpProductService;
    }

    public override IActionResult Index()
    {
        var products = _madeUpProductService.GetProductsByPage(page);
    ...
    }

To wire up a concrete instance of IMadeUpProductService, use a composer:

    using Umbraco.Cms.Core.Composing;
    using Umbraco.Cms.Core.DependencyInjection;
    using Umbraco.Extensions;

    namespace MyWebsite.Composers
    {
        public class RegisterSuperSiteServiceComposer : IUserComposer
        {
            public void Compose(IUmbracoBuilder builder)
            {
                builder.Services.AddUnique<IMadeUpProductService, MadeUpProductService>();
             
            }
        }
    }

Replace Umbraco's default RenderController

You can replace Umbraco's default implementation of RenderController with your own custom controller for all MVC requests. This is possible by assigning your own default controller type in the Umbraco setup during initialization.

You can achieve this by updating the options for UmbracoRenderingDefaultsOptions in the ConfigureServices method in the Startup.cs class.

First of all you have to create your own controller. Your custom implementation of RenderController should either inherit from the core RenderController as in the examples above or implement the IRenderController interface.

Implement the IRenderController:

public class MyRenderController : IRenderController
{
    public IActionResult Index()
    {
        return new OkObjectResult("Hello from your custom Render Controller");
    }
}

Or inherit from RenderController

public class MyRenderController : RenderController
{
    public MyRenderController(ILogger<RenderController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor) 
        : base(logger, compositeViewEngine, umbracoContextAccessor)
    {
    }

    public override IActionResult Index()
    {
        // Add some custom logic here. 
        return CurrentTemplate(CurrentPage);
    }
}

The last step is to configure Umbraco to use your implementation. You can do that in the ConfigureServices method in the Startup.cs class.

public void ConfigureServices(IServiceCollection services)
{
    services.AddUmbraco(_env, _config)
        .AddBackOffice()             
        .AddWebsite()
        .AddComposers()
        .Build();

    // Configure Umbraco Render Controller Type
    services.Configure<UmbracoRenderingDefaultsOptions>(c =>
    {
        c.DefaultControllerType = typeof(MyRenderController);
    });
}
PreviousRouting requirements for backoffice authenticationNextCustom MVC Routes

Last updated 1 year ago

Injecting services into your controller constructors is possible with Umbraco's underlying dependency injection implementation. See for more info on this.

See for further information.

Composing
Services and Helpers