Search code examples
c#asp.net-corerazor-pages.net-8.0asp.net-core-localization

ASP.NET Core Razor Pages - Generate route conditionally with asp-route-


I've implemented routing-based localization for my ASP.NET Core project (.NET 8). Basically, these requirements are met:

  • when the root is requested ( path = '/' ) the CultureInfo.CurrentCulture is set to ru-RU
  • when the root is requested as '/en' the CultureInfo.CurrentCulture is set to en-US
  • for the default culture, when '/ru' is requested (or '/ru/[whatever]') the request returns "moved permanently (301)" with location set to '/' (or '/[whatever]' respectively)

But when I generate a link to the home page with:

<a asp-page="/Index" asp-route-lang="@CultureInfo.CurrentCulture.TwoLetterISOLanguageName">Home</a>

I get https://localhost/ru for the default culture (ru-RU), and https://localhost/en for English (en-US).

Question:

How can I get rid of /ru part when generating a URL for default culture (instead of having https://localhost/ru I need to get just https://localhost)? I can use a condition in every asp-route-lang="..." but that is not a good way of doing it.


Solution

  • Think that this can be done to remove the default culture (route path) in the route via the custom tag helper.

    As the below, you can compare the value of the asp-route-lang attribute against the default culture of your application. If both values are same, you overwrite the href attribute.

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Razor.TagHelpers;
    using Microsoft.Extensions.Options;
    using System;
    
    [HtmlTargetElement("a")]
    public class AnchorWithLangTagHelper : TagHelper
    {
        [HtmlAttributeName("asp-route-lang")]
        public string Lang { get; set; }
    
        private readonly RequestLocalizationOptions _options;
    
        public AnchorWithLangTagHelper(IOptions<RequestLocalizationOptions> options)
        {
            _options = options.Value;
        }
    
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            // Remove the Lang from route if provided Lang is default culture 
            if (!String.IsNullOrEmpty(Lang)
                && _options.DefaultRequestCulture.UICulture.TwoLetterISOLanguageName.Equals(Lang, StringComparison.OrdinalIgnoreCase))
            {
                var generatedHref = output.Attributes["href"].Value.ToString();
                generatedHref = generatedHref.Replace($"/{Lang}/", "/");
    
                output.Attributes.SetAttribute("href", generatedHref);
            }
        }
    }
    

    And add the custom tag helper to make it available in all views via @addTagHelper in the Views/_ViewImport.cshtml.

    @addTagHelper <Namespace of AnchorWithLangTagHelper>.AnchorWithLangTagHelper, <Project Namespace>
    

    Demo

    enter image description here