Fading Coder

One Final Commit for the Last Sprint

Home > Notes > Content

Implementing Multilingual Form Validation with a Single Resx File in ASP.NET 8

Notes May 12 2

This guide details the integration of multilingual form validation error messages using a centralized resource file in an ASP.NET Core 8 application. The approach leverages shared resources to consolidate localization strings across controllers and views, eliminating redundancy.

The core setup begins in Program.cs by registering localization services and configuring request culture handling:

private static void ConfigureLocalizationServices(WebApplicationBuilder builder)
{
    builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
    builder.Services.AddMvc()
        .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
        .AddDataAnnotationsLocalization(options =>
        {
            options.DataAnnotationLocalizerProvider = (type, factory) =>
                factory.Create(typeof(SharedResource));
        });

    builder.Services.Configure<RequestLocalizationOptions>(options =>
    {
        var supportedCultures = new[] { "en", "fr", "de", "it" };
        options.SetDefaultCulture(supportedCultures[0])
               .AddSupportedCultures(supportedCultures)
               .AddSupportedUICultures(supportedCultures);
    });
}

private static void ApplyLocalizationMiddleware(WebApplication app)
{
    app.UseRequestLocalization();
}

A marker class named SharedResource is defined to act as a reference point for the localization system. This class must reside in the root namespace and is used to resolve resource files dynamicallly:

namespace SharedResources03
{
    public class SharedResource
    {
        // Marker class for shared localization resources
    }
}

Language-specific resource files are created under a Resources folder with names like SharedResource.en.resx, SharedResource.fr.resx, etc., containing localized validation messages.

Model validation is handled via data annotations with placeholder strings that will be replaced at runtime based on the current culture:

public class LocalizationExampleViewModel
{
    [Required(ErrorMessage = "The UserName field is required.")]
    [Display(Name = "UserName")]
    public string? UserName { get; set; }

    [EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
    [Display(Name = "Email")]
    public string? Email { get; set; }

    public bool IsSubmit { get; set; } = false;
}

In the controller, IStringLocalizer<SharedResource> is injected to retrieve localized messages for custom error displays:

public IActionResult LocalizationExample(LocalizationExampleViewModel model)
{
    if (model.IsSubmit && !ModelState.IsValid)
    {
        ModelState.AddModelError("", _stringLocalizer["Please correct all errors and submit again"]);
    }
    else
    {
        ModelState.Clear();
    }

    return View(model);
}

To ensure compatibility with Bootstrap’s styling, client-side JavaScript synchronizes ASP.NET’s default .input-validation-error class with Bootstrap’s .is-invalid class:

<script type="text/javascript">
    window.addEventListener("DOMContentLoaded", () => {
        document.querySelectorAll("input.input-validation-error")
            .forEach(elem => elem.classList.add("is-invalid"));
    });
</script>

Views use standard tag helpers for rendering validation messages and incorporate the script partial to maintain visual consistency. The novalidate attribute is applied to prevent browser-native validation, ensuring only server-side, localized validation is shown.

Language selection is managed through a cookie-based mechanism, where user preference is stored in the .AspNetCore.Culture cookie, allowing persistent language settnigs across sessions.

Tags: ASP.NET Core

Related Articles

Designing Alertmanager Templates for Prometheus Notifications

How to craft Alertmanager templates to format alert messages, improving clarity and presentation. Alertmanager uses Go’s text/template engine with additional helper functions. Alerting rules referenc...

Deploying a Maven Web Application to Tomcat 9 Using the Tomcat Manager

Tomcat 9 does not provide a dedicated Maven plugin. The Tomcat Manager interface, however, is backward-compatible, so the Tomcat 7 Maven Plugin can be used to deploy to Tomcat 9. This guide shows two...

Skipping Errors in MySQL Asynchronous Replication

When a replica halts because the SQL thread encounters an error, you can resume replication by skipping the problematic event(s). Two common approaches are available. Methods to Skip Errors 1) Skip a...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.