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?
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?
Share Improve this question edited Feb 17 at 8:03 DarkBee 15.6k8 gold badges72 silver badges116 bronze badges asked Feb 14 at 13:37 Max BündchenMax Bündchen 1,36217 silver badges38 bronze badges1 Answer
Reset to default 0When 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:
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; } }
In the
Resources\SharedResource.fr.resx
resource file, add the translated value: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);
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):