URL routing
Map incoming URLs to content and extend routing with partial routers, events, and custom parameters in CMS 13.
URL routing in Optimizely Content Management System (CMS 13) maps incoming URLs to content and generates friendly URLs for outgoing content references. Use routing to resolve content by language, apply partial routers for custom URL segments, and define route parameters.
CMS separates routing into two layers. Content URL routing resolves and generates content URLs independent of web context. Endpoint routing in ASP.NET Core extends content URL routing to map requests to MVC controllers or Razor Pages.
Default routing
Default routing resolves content from URLs and maps requests to controllers or Razor Pages without additional configuration.
Endpoints
Endpoints define the URL patterns that CMS matches against incoming requests. The following endpoints are registered by default:
- Shell modules register endpoints to support routing to module controllers.
- CMS registers a wildcard endpoint that routes to content and maps the request to a matching MVC controller or Razor Page.
Standard MVC routes like "{controller}/{action}" are not registered by default. Call ASP.NET Core extension methods like MapRazorPages or MapControllerRoute to register standard MVC endpoints.
Controller or Razor Page routing
Controller and Razor Page routing determines which template renders the resolved content. The framework resolves a URL to content, then queries EPiServer.Web.TemplateResolver for the matching template. The template is an MVC controller, Razor Page, or custom endpoint.
The framework matches any remaining URL path against the endpoint parameters. If no endpoint matches the URL or no template matches the routed content, the framework returns a 404 response.
Extend routing
Extend routing to customize how CMS resolves incoming URLs and generates outgoing URLs. Options include subscribing to routing events, registering partial routers, defining custom content roots, and adding route parameters.
Access checks
Authentication is not available during routing because .AddRouting() runs before .AddAuthentication() in ASP.NET Core. Authorization runs after authentication and evaluates the user against the episerver:read policy.
Do not perform access checks in partial routers or routing event handlers.
Request language
The request language (ContentLanguage.PreferredCulture and IContentLanguageAccessor.Language) is not set until routing completes. Do not rely on request language in partial routers. Pass the language explicitly when loading content through IContentLoader. The routed language is available in the routing context passed to partial routers and routing event handlers.
Events
Routing events fire during incoming URL resolution and outgoing URL generation. Subscribe to these events to intercept or modify routing behavior.
The EPiServer.Core.Routing.IContentUrlResolverEvents interface exposes events for incoming routing:
ResolvingUrl– Raised before default routing runs. Set the matching content in the event handler to override default resolution.ResolvedUrl– Raised after default routing runs. Replace the routed content in the event handler.
The EPiServer.Core.Routing.IContentUrlGeneratorEvents interface exposes events for outgoing URL generation:
GeneratingUrl– Raised before URL generation. Modify the URL in the event handler.GeneratedUrl– Raised after URL generation. Modify the generated URL in the event handler.
Partial routing
Register a partial route to handle any remaining URL path after content routing completes. For details, go to Partial routing.
Custom content roots
A custom content root is a starting point for content routing. Implement EPiServer.Core.Routing.Pipeline.IContentRouteRegister and register the implementation in the dependency injection container. Optionally, define static segments in the implementation to prepend the content route.
Route parameters
Route parameters let the framework match remaining URL path segments to controller action parameters. When a remaining path exists after content routing, the framework matches it against endpoint parameters. If the remaining path is a single segment matching a controller action, the framework routes to that action.
Define custom route parameters with MapTemplate on IContentEndpointRouteBuilder. Call MapContent on IEndpointRouteBuilder to get the IContentEndpointRouteBuilder instance.
The following example registers actions with skip and take parameters for a controller:
app.UseEndpoints(endpoints => {
endpoints.MapContent()
.MapTemplate<PaginatingController>("{action}/{skip:int}/{take:int?}");
});Updated 11 days ago
