8

I started playing around with Tridion and DXA just recently, and I'm having problems to understand how custom routes work.

I have a Component Template which has its own DXA view, view model, controller, and action. I've created the correspondent objects in Tridion and the classic examples work properly.

I need to be able to configure custom routes to the action in order to receive parameters in the URL (eg. /books/{genre}/{year}) but I couldn't find how. Can you help me there?

Reading some other questions here I found some people suggesting to do the routing in Global.asax. This works, but the result is the rendering of the Component Template view only. I need to be able to route the whole page, being able to read the URL parameters.

Looking forward to your help!

2 Answers 2

5

After struggling a bit with the matter, I found an alternative way of handling this. I'm not sure it's the best solution, though.

1) Add the custom route with the URL parameters to the Global.asax redirecting to the page controller:

routes.MapRoute(
           "BooksCustomRoute",
           "books/{genre}/{year}",
           new { controller = "Page", action = "Page", pageUrl = "books/index" },
           new { pageId = @"^(.*)?$" }
        ).DataTokens.Add("area", "Core");

2) Once your component template action gets called, you will be able to retrieve the parameters from the route data:

public ActionResult Entity(CustomViewModel entity)
{
    string genre = Request.RequestContext.RouteData.Values["genre"]?.ToString();
    string year = Request.RequestContext.RouteData.Values["year"]?.ToString();

    return View(entity.MvcData.ViewName, entity);
}

This way I was able to pass and retrieve URL parameters loading the whole page instead of the single action/view.

If anyone has a better idea, please let me know.

2
  • It's better to override the EnrichModel method instead of the Entity method. Commented Oct 24, 2016 at 16:47
  • If you really want your URL parameters in the URL path, then this seems like a valid approach. You could also use URL query parameters, in which case you don't need a separate route (again, see ListController as an example). Commented Oct 24, 2016 at 16:49
3

DXA uses a rather unusual, composite Model and View rendering flow: a Page Model contains Region Models which in turn contain Entity Models.

Most incoming HTTP requests are handled by a Page Controller (see Global.asax.cs: the Page Controller handles all URLs which are not explicitly routed to some other controller). The Page Controller retrieves the (composite) Page Model and selects a Page View.

Normally, the Page View doesn't render the entire Page Model itself, though: it delegates rendering of the Regions to Region Views using the @Html.DxaRegion or @Html.DxaRegions helper methods. Technically speaking, a combination of a Region Controller and Region View is used to render a Region Model.

The Region View, in turn, normally delegates rendering of the Entity Models to Entity Views (using @Html.DxaEntity or @Html.DxaEntities) . Again, a combination of Entity Controller and Entity View is used to render an Entity Model.

For Entity Models, it is possible to configure a custom Entity Controller in CM (in the CT metadata). Such a custom Entity Controller should inherit from EntityController and should override the EnrichModel method. This method will be invoked just before the Entity Model gets rendered and is intended to enrich the Entity Model, typically based on URL parameters.

See, for example: https://github.com/sdl/dxa-web-application-dotnet/blob/master/Sdl.Web.Mvc/Controllers/ListController.cs

1
  • Hi Rick, thanks for your answer but I had already tried customizing the URL for the Entity view/action/controller. The problem then is that the custom URL return was only the partial view, and my need was to route to the whole page. Commented Oct 24, 2016 at 8:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.