【问题标题】:Asp .NET 5 data annotation localization with a custom localizer带有自定义本地化器的 Asp .NET 5 数据注释本地化
【发布时间】:2016-03-27 18:41:53
【问题描述】:

我通过覆盖 IStringLocalizerFactoryIStringLocalizer 创建了自己的缓存 JSON 字符串本地化程序,它的工作原理就像一个魅力。

唯一的问题是我无法本地化数据注释,因为它们似乎不适用于自定义字符串本地化器。我尝试使用应该用于这种情况的ResourceType 属性(至少就我而言),但不是使用我的IStringLocalizer,而是尝试访问属性。这可能适用于默认的resx-localizer,但不适用于自定义的。

我可以在我的班级中创建重新路由到我的IStringLocalizer 的属性,但这很麻烦,只有在必要时才想这样做。

我的视图模型:

public class RegisterViewModel
{
    [Required]
    [Display(Name = "test", ResourceType = typeof(Lang))]
    public string Username { get; set; }
}

在我的cshtml 内部使用,如下所示:

<div class="form-group">
    <label asp-for="Username" class="col-md-2 control-label"></label>
    <div class="col-md-10">
        <input asp-for="Username" class="form-control" />
        <span asp-validation-for="Username" class="text-danger"></span>
    </div>
</div>

应该自动生成labeltextbox。但相反:

InvalidOperationException: Cannot retrieve property 'Name' because localization failed. Type 'Test.Models.Lang.Lang' is not public or does not contain a public static string property with the name 'test'.

轰隆隆。那是我的Lang 班级:

public class Lang
{
}

它没有通过索引器获取IStringLocalizer&lt;Lang&gt; 并搜索test 属性(这就是我试图让他做的事情),而是试图找到不存在的属性test

有什么方法可以改变查找的工作方式吗?我尝试通过services.Configure() 更改MvcDataAnnotationsLocalizationOptions,但没有效果。

或者是否可以直接更改从这些数据注释生成 HTML 代码的方式?

感谢您的帮助。

【问题讨论】:

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


    【解决方案1】:

    编辑:这当然行不通,因为 CreateDisplayMetadata() 只被调用一次然后被缓存,导致第一个“翻译”成为唯一的!我确实有另一个扩展 DefaultModelMetadataProvider 或添加 IDisplayMetadataProvider 的解决方案(仍然不确定这是正确或最好的方法......),所以如果有人仍然需要帮助,请告诉我:)

    旧的和错误的答案: 不知道是否有任何“更正确”的解决方案(如果有,请告诉我:) 解决方案,但这里有一个适用于 RC2 的解决方案:

    public class LocalizedDisplayMetadataProvider : IDisplayMetadataProvider
    {
        public String Translate(String key)
        {
            if(key != null && key.StartsWith("#"))
            {
                return key.TrimStart('#').ToUpper(); // Todo: Replace with real localization code (e.g. fetch from json)...
            }
            else
            {
                return key;
            }
        }
    
        public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
        {
            foreach(var attr in context.Attributes.OfType<DisplayAttribute>().Where(a => a.ResourceType == null))
            {
                attr.Name = this.Translate(attr.Name);
                attr.Description = this.Translate(attr.Description);
                attr.GroupName = this.Translate(attr.GroupName);
                attr.Prompt = this.Translate(attr.Prompt);
                attr.ShortName = this.Translate(attr.ShortName);
            }
        }
    }
    

    然后在ConfigureServices方法中注册:

    services.Configure<MvcOptions>(m =>
            {
                m.ModelMetadataDetailsProviders.Add(new LocalizedDisplayMetadataProvider());
    
            });
    

    这将对 DisplayAttribute 上以“#”开头的所有字符串(而不是 ResourceType 集)进行本地化,并且可以轻松扩展以处理 ValidationAttribute。

    【讨论】:

    • 我正在努力解决同样的问题。所以,如果我想让 DataAnnotations 动态工作(每次检查新的本地化版本),我不应该依赖 StringLocalizer 是吗?您的 LocalizedDisplayMetadataProvider 是否仍然可以正常工作?我在 .Net 5 上
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 2018-11-30
    相关资源
    最近更新 更多