ASP.NET Core模型绑定消息翻译失败,求可行解决方案
解决ASP.NET Core模型绑定验证消息翻译失效的问题
我之前也碰到过类似的困扰,ASP.NET Core确实取消了MVC时代的语言包,得靠自己配置本地化。结合你的代码,我整理几个关键的修复点和替代方案:
一、先排查资源文件配置的核心问题
如果你想用资源文件来管理翻译,必须严格遵循命名和位置规则:
- 资源文件要放在你设置的
Resources文件夹下,全局模型绑定消息的资源文件名必须是Microsoft.AspNetCore.Mvc.ModelBinding.pt-BR.resx(对应葡萄牙语巴西地区),注意命名空间要匹配Microsoft.AspNetCore.Mvc.ModelBinding - 右键资源文件→属性→设置自定义工具为
PublicResXFileCodeGenerator,确保资源类是公开的,不然框架无法访问 - 资源文件里的键要和模型绑定消息的键对应,比如
AttemptedValueIsInvalid对应的值就是你要的葡萄牙语翻译
二、修正服务注册的顺序和重复调用问题
你的代码里在Register方法先调用了services.AddMvc(),然后在TraduzirMensagensModelValidation里又调用了一次services.AddMvc(),这会覆盖之前的MVC配置,导致你的设置不生效。调整后的代码应该合并配置:
修正后的Register方法
public static void Register(IServiceCollection services, IConfiguration configuration) { #region aplication // 合并MVC和本地化配置,避免重复AddMvc() services.AddMvc(options => { options.AddNavigationBootstrap3Views(); }) .AddLocalization(options => { options.ResourcesPath = "Resources"; }) .AddDataAnnotationsLocalization() .AddViewLocalization(); // 单独配置模型绑定消息(如果不用资源文件,直接硬编码) services.Configure<MvcOptions>(o => { o.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor((x, y) => "O valor '{0}' não é válido para {1}."); o.ModelBindingMessageProvider.SetMissingBindRequiredValueAccessor(x => "Não foi fornecido um valor para o campo {0}."); o.ModelBindingMessageProvider.SetMissingKeyOrValueAccessor(() => "Campo obrigatório."); o.ModelBindingMessageProvider.SetMissingRequestBodyRequiredValueAccessor(() => "É necessário que o body na requisição não esteja vazio."); o.ModelBindingMessageProvider.SetNonPropertyAttemptedValueIsInvalidAccessor((x) => "O valor '{0}' não é válido."); o.ModelBindingMessageProvider.SetNonPropertyUnknownValueIsInvalidAccessor(() => "O valor fornecido é inválido."); o.ModelBindingMessageProvider.SetNonPropertyValueMustBeANumberAccessor(() => "O campo deve ser um número."); o.ModelBindingMessageProvider.SetUnknownValueIsInvalidAccessor((x) => "O valor fornecido é inválido para {0}."); o.ModelBindingMessageProvider.SetValueIsInvalidAccessor((x) => "O valor fornecido é inválido para {0}."); o.ModelBindingMessageProvider.SetValueMustBeANumberAccessor(x => "O campo {0} deve ser um número."); o.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(x => "O valor nulo é inválido."); }); services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new List<CultureInfo> { new CultureInfo("pt-BR"), }; options.DefaultRequestCulture = new RequestCulture(culture: "pt-BR", uiCulture: "pt-BR"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; }); services.AddMemoryCache(); services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN"); services.AddSingleton(provider => configuration); #endregion #region Presentation services.AddAuthentication(configuration); services.AddTransient<IUserClaimsPrincipalFactory<Conta>, ApplicationUserClaimsPrincipalFactory>(); services.AddAuthorization(options => HelperAutorization.Register(options)); services.AddCustonNavigation(configuration.GetSection("NavigationOptions")); #endregion }
三、必须添加本地化中间件到管道
很多人会忽略这一步!在Startup.cs的Configure方法里,一定要在UseMvc()之前添加本地化中间件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 其他中间件... app.UseRequestLocalization(); // 必须放在UseMvc之前 app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
四、替代方案:使用FluentValidation实现更灵活的本地化
如果自带的本地化还是不好用,推荐用FluentValidation这个第三方库,它的本地化支持更成熟:
- 安装包:
Install-Package FluentValidation.AspNetCore - 配置服务:
services.AddMvc() .AddFluentValidation(fv => { fv.RegisterValidatorsFromAssemblyContaining<YourValidator>(); // 启用本地化 fv.ImplicitlyValidateChildProperties = true; fv.LocalizationEnabled = true; });
- 可以直接使用官方提供的葡萄牙语资源包,或者自定义资源文件,比自带的模型绑定消息配置更直观。
内容的提问来源于stack exchange,提问作者Gabriel Fernando
相关产品推荐
相关产品推荐

