使用App_GlobalResources在ASP.NET MVC 4中进行本地化

时间:2013-05-28 10:39:05

标签: asp.net asp.net-mvc-4 localization app-globalresources

我正在努力完成两件事:

  1. 本地化“FieldMustBeDate”和“FieldMustBeNumeric”的“内置”错误消息。
  2. 本地化您遇到的其他一些错误消息,例如“PropertyValueRequired”。
  3. 通过对问题1使用http://forums.asp.net/t/1862672.aspx/1而对问题2使用MVC 4 ignores DefaultModelBinder.ResourceClassKey,我设法让两者都在本地工作。

    但是,当我发布到网站时,“内置”错误消息会默认返回到英语,而其他错误消息会保持本地化。

    我已经阅读了几个应该避免使用App_GlobalResources的地方,但是我不能在不使用它的情况下完成问题1。

    我创建了一个名为“WebResources.resx”的.resx文件,将Build Action设置为“Embedded”,将Copy to Output Directory设置为“Do no Copy”,将Custom Tool设置为“PublicResXFileCodeGenerator”,将自定义工具命名空间设置为“资源”。 项目本身设置为仅发布所需的文件。

    我的Global.asax.cs包含以下(相关)代码:

      ClientDataTypeModelValidatorProvider.ResourceClassKey = "WebResources";  
      DataAnnotationsModelValidatorProvider.RegisterAdapter(
      typeof(RequiredAttribute),
      typeof(MyRequiredAttributeAdapter));
    

    类MyRequiredAttributeAdapter包含以下代码:

    public class MyRequiredAttributeAdapter : RequiredAttributeAdapter
    {
        public MyRequiredAttributeAdapter(
            ModelMetadata metadata,
            ControllerContext context,
            RequiredAttribute attribute
        )
            : base(metadata, context, attribute)
        {
            if (attribute.ErrorMessageResourceType == null)
            {
                attribute.ErrorMessageResourceType = typeof(Resources.WebResources);
            }
            if (attribute.ErrorMessageResourceName == null)
            {
                attribute.ErrorMessageResourceName = "PropertyValueRequired";
            }
        }
    }
    

    这是在本地工作,但有人知道如何在发布“内置”消息后才能使用吗?

    感谢您的帮助!

    祝你好运, 安德烈亚斯

2 个答案:

答案 0 :(得分:5)

我自己想出了这个。如果您尝试完成上述操作,则必须分离本地化的错误消息。

为其他错误消息fx“PropertyValueRequired”创建* .resx文件,并将Build Action设置为“Embedded”,将Copy to Output Directory设置为“Do no Copy”,将Custom Tool设置为“PublicResXFileCodeGenerator”,将自定义工具命名空间设置为“资源”。

在我的情况下,我已将“PropertyValueRequired”移动到名为LocalDanish.resx的文件(仍在App_GlobalResources文件夹中)并更改了我的“MyRequiredAttributeAdapter”中的行

attribute.ErrorMessageResourceType = typeof(Resources.WebResources);

attribute.ErrorMessageResourceType = typeof(Resources.LocalDanish);

为了使“内置”错误消息起作用,您必须创建两个* .resx文件。我创建了WebResources.resx和WebResources.da.resx。不要更改任何内容,默认情况下保留它们的设置(Build Action to“Content”等)。我想网站会自动查找我的案例中的* .da.resx文件,因为我已经在我的WebConfig中设置了全球化:

<globalization uiCulture="da-DK" culture="da-DK"/>

希望这有助于任何人。

祝你好运, 安德烈亚斯

答案 1 :(得分:1)

我在原帖中做了一些小的补充,在我的情况下没有翻译所有的消息。 (字符串长度和无效的属性值)

按照上述步骤,创建* .resx文件,设置其属性,然后在web.config中设置区域设置,如Andreas所述。

然后创建几个适配器:

// As described in original post:
public class LocalizedRequiredAttributeAdapter : RequiredAttributeAdapter
{
    public LocalizedRequiredAttributeAdapter(
        ModelMetadata metadata,
        ControllerContext context,
        RequiredAttribute attribute
    )
        : base(metadata, context, attribute)
    {
        if (attribute.ErrorMessageResourceType == null)
            attribute.ErrorMessageResourceType = typeof(Resources.Resources);
        if (attribute.ErrorMessageResourceName == null)
            attribute.ErrorMessageResourceName = "PropertyValueRequired";
    }
}

// Addition to original post:
public class LocalizedStringLengthAttributeAdapter : StringLengthAttributeAdapter
{
    public LocalizedStringLengthAttributeAdapter(
        ModelMetadata metadata,
        ControllerContext context,
        StringLengthAttribute attribute
    )
        : base(metadata, context, attribute)
    {
        if (attribute.ErrorMessageResourceType == null)
            attribute.ErrorMessageResourceType = typeof(Resources.Resources);
        if (attribute.ErrorMessageResourceName == null)
            attribute.ErrorMessageResourceName = "StringLengthAttribute_ValidationError";
    }
}

在Global.asax.cx中:

// Addition to original post: (Used for "PropertyValueInvalid")
DefaultModelBinder.ResourceClassKey = "Resources";

// As described in original post:
ClientDataTypeModelValidatorProvider.ResourceClassKey = "Resources";
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredAttribute), typeof(LocalizedRequiredAttributeAdapter));
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(StringLengthAttribute), typeof(LocalizedStringLengthAttributeAdapter));