如何在ASP.NET Core中实现DisplayFormat数据注解的本地化
实现方案
你完全可以通过自定义特性 + 模型元数据扩展的方式,用已配置的IStringLocalizer<SharedResource>完成DisplayFormat的本地化,步骤如下:
1. 定义继承原生DisplayFormatAttribute的本地化特性
保留原生DisplayFormat的所有能力,仅新增资源key的配置属性:
public class LocalizedDisplayFormatAttribute : DisplayFormatAttribute { /// <summary> /// 格式字符串对应的共享资源Key /// </summary> public string DataFormatStringResourceKey { get; set; } /// <summary> /// 空值显示文本对应的共享资源Key /// </summary> public string NullDisplayTextResourceKey { get; set; } }
2. 实现自定义显示元数据提供器
通过这个提供器在模型元数据初始化阶段,自动从共享资源读取对应的字符串替换到特性属性中:
public class LocalizedDisplayFormatMetadataProvider : IDisplayMetadataProvider { private readonly IStringLocalizer<SharedResource> _localizer; // 直接注入你已配置的共享资源本地器 public LocalizedDisplayFormatMetadataProvider(IStringLocalizer<SharedResource> localizer) { _localizer = localizer; } public void CreateDisplayMetadata(DisplayMetadataProviderContext context) { var localizedFormatAttr = context.Attributes.OfType<LocalizedDisplayFormatAttribute>().FirstOrDefault(); if (localizedFormatAttr == null) return; // 替换格式字符串 if (!string.IsNullOrWhiteSpace(localizedFormatAttr.DataFormatStringResourceKey)) { localizedFormatAttr.DataFormatString = _localizer[localizedFormatAttr.DataFormatStringResourceKey]; } // 替换空值显示文本 if (!string.IsNullOrWhiteSpace(localizedFormatAttr.NullDisplayTextResourceKey)) { localizedFormatAttr.NullDisplayText = _localizer[localizedFormatAttr.NullDisplayTextResourceKey]; } } }
3. 注册自定义元数据提供器
修改你现有的AddLocalizationServices扩展方法,新增一行服务注册即可,不需要修改原有本地化配置:
public static IServiceCollection AddLocalizationServices(this IServiceCollection services) { // 新增:注册自定义元数据提供器 services.AddSingleton<IDisplayMetadataProvider, LocalizedDisplayFormatMetadataProvider>(); // 你原有配置完全保留 services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("es-MX") }; options.DefaultRequestCulture = new RequestCulture("en-US"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; }); services.AddLocalization(options => { options.ResourcesPath = "Resources"; } ); services.AddControllersWithViews() .AddRazorRuntimeCompilation() .AddViewLocalization(options => { options.ResourcesPath = "Resources"; }) .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => { return factory.Create(typeof(SharedResource)); }; }); return services; }
4. 视图模型中使用
直接在属性上标注特性,传入资源key即可,原生DisplayFormat的ApplyFormatInEditMode等属性都可以正常使用:
public class YourViewModel { // 示例:日期格式 + 空值提示本地化 [LocalizedDisplayFormat( DataFormatStringResourceKey = "Common_Date_Format", NullDisplayTextResourceKey = "Common_NoData_Tip", ApplyFormatInEditMode = true)] public DateTime? CreateTime { get; set; } // 示例:金额格式本地化 [LocalizedDisplayFormat(DataFormatStringResourceKey = "Common_Currency_Format")] public decimal Amount { get; set; } }
最后在你的SharedResource资源文件中添加对应语言的key值即可,切换文化时会和其他本地化逻辑自动同步,不需要额外适配。
内容的提问来源于stack exchange,提问作者user351479
相关产品推荐
相关产品推荐

