【问题标题】:Localization in ASP.NET MVC 4 using App_GlobalResources使用 App_GlobalResources 在 ASP.NET MVC 4 中进行本地化
【发布时间】:2013-05-28 10:39:05
【问题描述】:

我正在努力完成两件事:

  1. 本地化“FieldMustBeDate”和“FieldMustBeNumeric”的“内置”错误消息。
  2. 本地化您可能遇到的其他一些错误消息,例如“PropertyValueRequired”。

通过使用http://forums.asp.net/t/1862672.aspx/1 处理问题1 和MVC 4 ignores DefaultModelBinder.ResourceClassKey 处理问题2,我已经设法让两者都在本地工作。

但是,一旦我发布到网站,“内置”错误消息就会默认恢复为英文,而其他错误消息会保持本地化。

我已经阅读了几个应该避免使用 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";
        }
    }
}

这是在本地工作,但是有没有人知道如何让“内置”消息在发布后工作?

感谢您的帮助!

最好的问候, 安德烈亚斯

【问题讨论】:

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


    【解决方案1】:

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

    为其他错误消息 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。不要更改任何内容,将它们的设置保留为默认值(将操作构建为“内容”等)。我猜网站会自动查找 *.da.resx 文件,因为我在 WebConfig 中设置了全球化:

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

    希望这对任何人都有帮助。

    最好的问候, 安德烈亚斯

    【讨论】:

    • 谢谢!这个问题一直让我发疯!
    【解决方案2】:

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

    按照上述步骤,创建 *.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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-23
      相关资源
      最近更新 更多