Answers:
如何编写自定义属性:
public class LocalizedDisplayNameAttribute: DisplayNameAttribute
{
public LocalizedDisplayNameAttribute(string resourceId)
: base(GetMessageFromResource(resourceId))
{ }
private static string GetMessageFromResource(string resourceId)
{
// TODO: Return the string from the resource file
}
}
可以这样使用:
public class MyModel
{
[Required]
[LocalizedDisplayName("labelForName")]
public string Name { get; set; }
}
如果使用MVC 3和.NET 4,则可以Display
在System.ComponentModel.DataAnnotations
名称空间中使用new 属性。该属性替换该DisplayName
属性,并提供更多功能,包括本地化支持。
在您的情况下,可以这样使用它:
public class MyModel
{
[Required]
[Display(Name = "labelForName", ResourceType = typeof(Resources.Resources))]
public string name{ get; set; }
}
另外请注意,此属性不适用于App_GlobalResources
或中的资源App_LocalResources
。这与GlobalResourceProxyGenerator
这些资源使用的自定义工具()有关。相反,请确保将资源文件设置为“嵌入式资源”,并使用“ ResXFileCodeGenerator”自定义工具。
(作为补充说明,您不应该使用MVC App_GlobalResources
或将其App_LocalResources
与MVC 一起使用。您可以在此处阅读有关为何如此的更多信息)
Name = "labelForName"
也可以使用代替Name = nameof(Resources.Resources.labelForName)
。
如果打开资源文件并将access修饰符更改为public或internal,它将从您的资源文件生成一个类,该类使您可以创建强类型的资源引用。
这意味着您可以改为执行以下操作(使用C#6.0)。然后,您不必记住名字是小写还是驼峰。您可以通过查找所有引用来查看其他属性是否使用相同的资源值。
[Display(Name = nameof(PropertyNames.FirstName), ResourceType = typeof(PropertyNames))]
public string FirstName { get; set; }
我知道为时已晚,但我想添加此更新:
我正在使用Phil Haack提出的ConventionalModel Model Metadata Provider,它更强大,更容易应用,请看一下: ConventionalModelMetadataProvider
如果您想支持多种类型的资源,请在这里:
public class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
private readonly PropertyInfo nameProperty;
public LocalizedDisplayNameAttribute(string displayNameKey, Type resourceType = null)
: base(displayNameKey)
{
if (resourceType != null)
{
nameProperty = resourceType.GetProperty(base.DisplayName,
BindingFlags.Static | BindingFlags.Public);
}
}
public override string DisplayName
{
get
{
if (nameProperty == null)
{
return base.DisplayName;
}
return (string)nameProperty.GetValue(nameProperty.DeclaringType, null);
}
}
}
然后像这样使用它:
[LocalizedDisplayName("Password", typeof(Res.Model.Shared.ModelProperties))]
public string Password { get; set; }
有关完整的本地化教程,请参见此页面。
通过选择资源属性,将“自定义工具”切换为“ PublicResXFileCodeGenerator”,并将操作构建为“嵌入式资源”,我得到了Gunders使用我的App_GlobalResources的答案。请注意下面的Gunders评论。
奇迹般有效 :)
public class Person
{
// Before C# 6.0
[Display(Name = "Age", ResourceType = typeof(Testi18n.Resource))]
public string Age { get; set; }
// After C# 6.0
// [Display(Name = nameof(Resource.Age), ResourceType = typeof(Resource))]
}
定义用于资源密钥的属性的名称,在C#6.0之后,您可以使用nameof
强类型支持而不是对密钥进行硬编码。
在控制器中设置当前线程的区域性。
Resource.Culture = CultureInfo.GetCultureInfo("zh-CN");
将资源的可访问性设置为公共
像这样在cshtml中显示标签
@Html.DisplayNameFor(model => model.Age)