Jerodev
Jerodev

Reputation: 33206

Generate route with one parameter replaced

I have created a website where localization is being done by the first parameter in my route. So each URL looks like /{lang}/... with lang being nl, en, fr, ....

In my header, I would like to add a language picker that redirects to the current page in the selected language. I have used the code below and it worked perfectly.

<a asp-route-lang="@lang.Code.ToString()">
    @lang.Name
</a>

However, when the current route contains other route parameters, these are all gone for the generated URL. Is there any way to tell the route generator to keep all other existing route parameters for the new URL?

I have different route definitions with different parameters, so there is no possibility to add them to the generated URL manually.

Upvotes: 2

Views: 478

Answers (2)

Jerodev
Jerodev

Reputation: 33206

The answer of NightOwl888 gave me the idea on how to solve this.

I take the RouteData from the current context and use this as the base for the route generator. In my foreach loop, I overwrite the lang parameter with the one that I need.

Now I can use the Url.Action() function with this data to generate the correct URL.

@{
    var routeValues = this.ViewContext.RouteData.Values;
    var controller = routeValues["controller"] as string;
    var action = routeValues["action"] as string;
}

@foreach (var lang in Model.SiteLanguages)
{
    routeValues["lang"] = lang.Code.ToString();

    <a href="@Url.Action(action, controller, routeValues)">
        @lang.Name.UcFirst()
    </a>
}

Upvotes: 1

NightOwl888
NightOwl888

Reputation: 56909

At minimum, you need to specify a controller and action when building a URL based on routing. Since for this special case (selecting a culture) they may change depending on the URL, you need to pull these values from the current request.

@{
var routeValues = this.ViewContext.RouteData.Values;
var controller = routeValues["controller"] as string;
var action = routeValues["action"] as string;
}
<ul>
    <li><a asp-controller="@controller" asp-action="@action" asp-route-lang="en">English</a></li>
    <li><a asp-controller="@controller" asp-action="@action" asp-route-lang="es">Español</a></li>
</ul>

All other route values are carried over from the current request, so it will automatically reuse them when generating the URL, but this doesn't work for controller and action.

Upvotes: 1

Related Questions