You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:06:01