ASP.NET MVC6可本地化的DisplayAttribute

时间:2015-11-01 14:21:49

标签: c# asp.net localization asp.net-core-mvc

我想知道是否有可能直接使用ASP.NET MVC6中的IHtmlLocalizer和POCO类?目前我有很少的viewmodel使用DisplayAttribute来显示视图和验证器中的翻译字符串,但它需要创建额外的静态类,并定义每个静态属性(遗憾的是,静态索引器在C#中是不可能的)。有没有更好的办法来完成这项工作?

我目前的代码:

[Display(Name = "TrackingDevice", ResourceType = typeof(TestResource))]
public string TrackingDevice { get; set; }

public class TestResource
{
    public static string TrackingDevice
    {
        get
        {
            //Here I call IHtmlLocalizer via IServiceLocator
            return "Field name";
        }
    }
}

4 个答案:

答案 0 :(得分:1)

我有点挣扎,最后成功地编译了这个问题的工作解决方案。感谢@Szymon Sasin的回答,虽然它不适用于最新版本且他的配置不完整,但它帮助我构建了这个解决方案。

首先,在Startup.cs配置本地化:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        //...
        services.AddLocalization(options => options.ResourcesPath = "Resources");
        services
            .AddMvc(mvcOptions =>
            {
                IServiceProvider provider = services.BuildServiceProvider();
                IStringLocalizer localizer = provider.GetService<IStringLocalizer<DisplayResources>>();
                mvcOptions.ModelMetadataDetailsProviders.Add(new DisplayAttributeLocalizationProvider(localizer));
            });
        //...
    }
}

其次,根据配置的ResourcePath验证您的文件夹结构。这里重要的是自定义资源类型的路径和其resx文件的路径应该是相对的。示例:

<root_proj_dir>/Resources/Resources_Common/DisplayResources.en.resx
<root_proj_dir>/Resources/Resources_Common/DisplayResources.bg.resx
<root_proj_dir>/Resources_Common/DisplayResources.cs

第三,定义您的自定义元数据提供商:

public sealed class DisplayAttributeLocalizationProvider : IDisplayMetadataProvider
{
    private IStringLocalizer _localizer;

    public DisplayAttributeLocalizationProvider(IStringLocalizer localizer)
    {
        _localizer = localizer;
    }

    public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
    {
        context.PropertyAttributes?
            .Where(attribute => attribute is DisplayAttribute)
            .Cast<DisplayAttribute>().ToList().ForEach(display =>
            {
                display.Name = _localizer[display.Name].Value;
            });
    }
}

第四,在视图模型中使用所有这些:

public class SomeViewModel
{
    [Display(Name = "Email")]
    public string Email { get; set; }
}

“电子邮件”值将是DisplayResources.xx.resx文件中查找的关键。

希望其他人能发现此信息有用!

答案 1 :(得分:0)

首先,在最新版本的ASP.NET 5 beta8中,您可以找到新功能,最新版本是DataAnnotations中的本地化。

1.在安装程序类中启用它

services.AddMvc()  
   .AddViewLocalization()  
   .AddDataAnnotationsLocalization();

2.使用适当配置的数据注释标记您的模型

using System.ComponentModel.DataAnnotations;
using AspNet5Localization.Resources;

namespace AspNet5Localization.Model
{
    public class Box
    {
        public long Id { get; set; }

        public double Height { get; set; }

        public double Width { get; set; }

        [Required(ErrorMessageResourceName = "BoxLengthRequired", ErrorMessageResourceType = typeof(AmazingResource))]
        [Range(1.0, 100.0, ErrorMessageResourceName = "BoxLengthRange", ErrorMessageResourceType = typeof(AmazingResource))]
        public double Length { get; set; }
    }
}

数据注释示例:

[Required(ErrorMessageResourceName = "SomeResourcePropertyName", ErrorMessageResourceType = typeof(SomeResourceType))]

答案 2 :(得分:0)

尝试使用类似的东西:

public sealed class DisplayAttributeLocalisationProvider : IDisplayMetadataProvider {
    private IHtmlLocalizer localiser;

    public DisplayAttributeLocalisationProvider(IHtmlLocalizer localiser) {
        this.localiser = localiser;
    }

    public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
        => context
            .PropertyAttributes
            .Where(attribute => attribute is DisplayAttribute)
            .Cast<DisplayAttribute>()
            .ToList()
            .ForEach(x =>
                x.Name = this
                    .localiser
                    .Html(x?.Name)
                    .Value);

要将其添加到配置使用:

private void ConfigureMvcOptions(MvcOptions options)
    {
        options
            .ModelMetadataDetailsProviders
                .Add(new DisplayAttributeLocalisationProvider(this.localiser));

我不确定它如何处理错误但与DisplayAttributes

配合使用

编辑: 更新到MVC6

答案 3 :(得分:0)

ASP.NET Core 1.0不支持基于Display属性的新引入的本地化方法的开箱即用本地化。一种方法是使用ASP.NET Core 1.0之前的方法进行资源文件的本地化。我已经实现了一个简单的演示项目,该项目展示了如何本地化display属性https://github.com/feradz/ASPNetCoreLocalization/wiki DataAnnotations.resx用于本地化Display属性。