ASP.NET Core 5如何本地化数据注解校验错误响应中自动生成的标题
解决ASP.NET Core校验错误默认标题本地化问题
问题根因
One or more validation errors occurred.是ASP.NET Core为校验失败的API响应自动生成的ValidationProblemDetails对象的默认Title字段值,由框架内置的InvalidModelStateResponseFactory硬编码生成,不会走常规DataAnnotation的本地化逻辑,因此直接在SharedResource.resx添加对应键的翻译条目无法生效。
解决步骤
- 保留你已完成的DataAnnotation本地化配置、以及
SharedResource.resx中键为One or more validation errors occurred.的翻译条目 - 在服务注册阶段替换框架默认的无效模型状态响应工厂,手动读取本地化资源替换默认标题
.NET 6及以上版本示例代码
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; using System.Globalization; var builder = WebApplication.CreateBuilder(args); // 保留你原有本地化服务注册逻辑 builder.Services.AddLocalization(opt => opt.ResourcesPath = "Resources"); builder.Services.AddControllers() .AddDataAnnotationsLocalization(opt => { // 保留你原有DataAnnotation本地化配置 opt.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResource)); }) .ConfigureApiBehaviorOptions(opt => { // 替换默认响应工厂 opt.InvalidModelStateResponseFactory = context => { // 获取本地化服务 var localizer = context.HttpContext.RequestServices .GetRequiredService<IStringLocalizer<SharedResource>>(); var validationProblem = new ValidationProblemDetails(context.ModelState) { // 替换为本地化后的标题 Title = localizer["One or more validation errors occurred."], Status = StatusCodes.Status400BadRequest }; return new BadRequestObjectResult(validationProblem) { ContentTypes = { "application/problem+json", "application/problem+xml" } }; }; }); // 保留你原有请求本地化中间件配置 var app = builder.Build(); var supportedCultures = new[] { new CultureInfo("de"), new CultureInfo("en"), new CultureInfo("zh-CN") }; app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("de"), SupportedCultures = supportedCultures, SupportedUICultures = supportedCultures }); app.MapControllers(); app.Run();
.NET 5及更早版本示例代码(Startup.cs)
在ConfigureServices方法中添加如下配置:
public void ConfigureServices(IServiceCollection services) { // 保留你原有本地化、控制器服务注册逻辑 services.AddLocalization(opt => opt.ResourcesPath = "Resources"); services.AddControllers() .AddDataAnnotationsLocalization(opt => { opt.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResource)); }) .ConfigureApiBehaviorOptions(opt => { opt.InvalidModelStateResponseFactory = context => { var localizer = context.HttpContext.RequestServices .GetRequiredService<IStringLocalizer<SharedResource>>(); var validationProblem = new ValidationProblemDetails(context.ModelState) { Title = localizer["One or more validation errors occurred."], Status = StatusCodes.Status400BadRequest }; return new BadRequestObjectResult(validationProblem) { ContentTypes = { "application/problem+json", "application/problem+xml" } }; }; }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 保留你原有请求本地化中间件配置 var supportedCultures = new[] { new CultureInfo("de"), new CultureInfo("en"), new CultureInfo("zh-CN") }; app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("de"), SupportedCultures = supportedCultures, SupportedUICultures = supportedCultures }); // 其他中间件配置... app.UseRouting(); app.UseEndpoints(endpoints => endpoints.MapControllers()); }
内容的提问来源于stack exchange,提问作者MJBZA
相关产品推荐
相关产品推荐

