Max Bündchen
Max Bündchen

Reputation: 1372

DataAnnotations validation messages still in English after setting pt-BR culture

I'm trying to get data annotations validation messages in Portuguese (pt-BR) but they remain in English even after setting the culture.

Here's what I've tried - in Program.cs:

var builder = WebApplication.CreateBuilder(args);

// Setting default culture
var culturaPtBr = new CultureInfo("pt-BR");
CultureInfo.DefaultThreadCurrentCulture = culturaPtBr;
CultureInfo.DefaultThreadCurrentUICulture = culturaPtBr;

// Configuring RequestLocalization
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    options.DefaultRequestCulture = new RequestCulture("pt-BR");
    options.SupportedCultures = new List<CultureInfo> { new("pt-BR") };
    options.SupportedUICultures = new List<CultureInfo> { new("pt-BR") };
    options.FallBackToParentCultures = false;
    options.FallBackToParentUICultures = false;
});

var app = builder.Build();

// Adding localization middleware
app.UseRequestLocalization();

My model class:

public class LoginRequest
{
    [Required]
    public string Usuario { get; set; }

    [Required]
    [StringLength(100, MinimumLength = 6)]
    public string Senha { get; set; }
}

When validation fails, I still get messages in English like "The Usuario field is required" instead of the Portuguese equivalent. I don't want to customize each validation message manually. How can I make data annotations use the built-in Portuguese translations?

Environment: ASP.NET Core 8 Core Web API

What am I missing?

Upvotes: 0

Views: 23

Answers (1)

Zhi Lv
Zhi Lv

Reputation: 21636

When validation fails, I still get messages in English like "The Usuario field is required" instead of the Portuguese equivalent. I don't want to customize each validation message manually. How can I make data annotations use the built-in Portuguese translations?

The issue might relate that you didn't provide the Resource File for Localization Data Annotation Messages.

You can check this tutorial: DataAnnotations localization. When configure the localization, we can use the following code to set the resources path to "Resources".

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

And use AddDataAnnotationsLocalization adds support for localized DataAnnotations validation messages through IStringLocalizer abstractions.

Based on the official localization sample, I add an API controller and test the localized DataAnnotation validation with the following steps:

  1. Add a Product class in the Models folder:

     public class Product
     {
         [Required(ErrorMessage = "ProductNameRequired")]
         public string Name { get; set; }
    
         [Range(1, 1000, ErrorMessage = "PriceRangeError")]
         public decimal Price { get; set; }
     }
    
  2. In the Resources\SharedResource.fr.resx resource file, add the translated value:

    resource file

  3. In the Program.cs file, use the following code to configure the localization:

     builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
    
     builder.Services.AddMvc()
         .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
         .AddDataAnnotationsLocalization();
     // </snippet_LocalizationConfigurationServices>
    
     builder.Services.AddControllers()
         .AddDataAnnotationsLocalization(options =>
         {
             var factory = builder.Services.BuildServiceProvider()
                 .GetRequiredService<IStringLocalizerFactory>();
             var localizer = factory.Create(typeof(SharedResource));
             options.DataAnnotationLocalizerProvider = (type, factory) => localizer;
         }); 
    
    
     builder.Services.AddTransient<IEmailSender, AuthMessageSender>();
     builder.Services.AddTransient<ISmsSender, AuthMessageSender>();
    
     // <snippet_RequestLocalizationOptionsConfiguration>
     builder.Services.Configure<RequestLocalizationOptions>(options =>
     {
         var supportedCultures = new[] { "fr", "en-US"};
         options.SetDefaultCulture(supportedCultures[0])
             .AddSupportedCultures(supportedCultures)
             .AddSupportedUICultures(supportedCultures);
     });
     // </snippet_RequestLocalizationOptionsConfiguration>
     builder.Services.AddEndpointsApiExplorer();
     builder.Services.AddSwaggerGen(c =>
     {
         c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Global Header Example", Version = "v1" }); 
     });
     var app = builder.Build();
    
     var localizationOptions = app.Services.GetRequiredService<IOptions<RequestLocalizationOptions>>();
     app.UseRequestLocalization(localizationOptions.Value);
    

    configure

  4. Add an API to check the validation:

     [Route("api/[controller]")]
     [ApiController]
     public class TodoController : ControllerBase
     {
         [HttpPost]
         public IActionResult AddProduct(Product product)
         {
    
             return Ok(product);
         }
     }
    

Then, when access the API, the output as below (the language/culture send via cookie):

result

Upvotes: 0

Related Questions