我通过覆盖IStringLocalizerFactory
和IStringLocalizer
创建了自己的缓存JSON字符串本地化程序,它就像一个魅力。
唯一的问题是我无法本地化数据注释,因为它们似乎无法使用自定义字符串本地化程序。我尝试使用ResourceType
属性,这个属性应该用于这种情况(至少就我而言),但不是使用我的IStringLocalizer
而是尝试访问属性。这可能适用于默认的resx
- 本地化程序,但不适用于自定义程序。
我可以在我的班级中创建属性,重新路由到我的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>
应自动生成label
和textbox
。但相反:
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'.
booom。那是我的Lang
课程:
public class Lang
{
}
而不是通过索引器获取IStringLocalizer<Lang>
并搜索test
属性(这就是我试图让他做的事情),它试图找到不存在的属性test
有没有办法改变查找的工作方式?我尝试通过MvcDataAnnotationsLocalizationOptions
更改services.Configure()
,但没有效果。
或者是否可以直接更改从这些数据注释生成HTML代码的方式?
感谢您的帮助。
答案 0 :(得分:0)
编辑:这当然不起作用,因为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。