Search code examples
c#asp.net-coreattributerouting

How to generate a URL with Attribute Routing based on the controller template and Action Template


I have the following URL template in the IdeasController:

[Controller]
[Route("/gemeente/{municipalityName}/election/{electionId}/ideas/"Name = "Ideas")]

public class IdeasController : Controller

I also have this Action with route template:

[Route("theme/{themeId}/",Name = "GetTheme")]
public IActionResult GetTheme(int themeId)
{
    Console.WriteLine("Get theme----------------------------");
    
    IEnumerable<Idea> ideas = _ideasManager.GetIdeasByTheme(themeId);
    GeneralTheme theme = _themeManager.GetGeneralTheme(themeId);
    IdeasByThemeDto ideasByThemeDto = new IdeasByThemeDto
    {
        Ideas = ideas,
        Theme = theme
    };
    ViewBag["Title"] = "Ideas by theme: " + theme.Name;
    
    return View("IdeasByTheme", ideasByThemeDto);
}

How can I generate a URL to arrive at gemeente/Dendermonde/election/1/ideas/theme/2 in the view?

Concrete example in view:

I have a collection of ideas, each idea has a theme with a themeId.

I want to generate a URL that appends the current URL (/gemeente/{municipalityName}/election/{electionId}/ideas/) with the theme id (theme/{themeId}), which basically combines the two ("Ideas" and "GetTheme") templates together.

In the view:

@Url.RouteUrl("GetTheme22", new { themeId = Model.Theme.Id })  //empty string

Note: municipality name and election id should also be dynamically inserted, based on the previous request.


Solution

  • Given the shown route templates you could generate a link using Url.RouteUrl:

    <a href="@Url.RouteUrl("GetTheme", new {municipalityName="Dendermonde", electionId=1, themeId=2})">Get Themes</a>
    

    which would resolve to

    <a href="gemeente/Dendermonde/election/1/ideas/theme/2">Get Themes</a>
    

    Reference Routing to controller actions in ASP.NET Core - Generate URLs by route

    how can MunicipalitName and electionId be dynamically inserted.

    How that information is passed to the view is up to personal preference and factors specific to the use case.

    Here, the following extracts the controller template parameters from the ViewBag assuming it was stored there from the previous request

    <a href="@Url.RouteUrl("GetTheme", new {
        municipalityName=ViewBag["MunicipalitName"], 
        electionId=ViewBag["electionId"], 
        themeId=Model.Theme.Id})">Get Themes</a>
    

    While the following assumes everything was stored in the Model

    <a href="@Url.RouteUrl("GetTheme", new {
        municipalityName=Model.MunicipalitName, 
        electionId=Model.ElectionId, 
        themeId=Model.Theme.Id})">Get Themes</a>