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

使用App_GlobalResources在ASP.NET MVC 4中进行本地化,asp.net,asp.net-mvc-4,localization,app-globalresources,Asp.net,Asp.net Mvc 4,Localization,App Globalresources,我正在努力完成两件事: 本地化“FieldMustBeDate”和“FieldMustBeNumeric”的“内置”错误消息 本地化您可能遇到的其他一些错误消息,例如“PropertyValueRequired” 通过对问题1和问题2使用,我已设法使这两个问题都在本地工作 然而,一旦我发布到一个网站,“内置”错误消息默认返回到英语,而其他错误消息保持本地化 我读过一些地方,认为应该避免使用App_GlobalResources,但是如果不使用它,我无法完成问题1 我已经创建了一个名为“WebRe

我正在努力完成两件事:

  • 本地化“FieldMustBeDate”和“FieldMustBeNumeric”的“内置”错误消息
  • 本地化您可能遇到的其他一些错误消息,例如“PropertyValueRequired”
  • 通过对问题1和问题2使用,我已设法使这两个问题都在本地工作

    然而,一旦我发布到一个网站,“内置”错误消息默认返回到英语,而其他错误消息保持本地化

    我读过一些地方,认为应该避免使用App_GlobalResources,但是如果不使用它,我无法完成问题1

    我已经创建了一个名为“WebResources.resx”的.resx文件,将构建操作设置为“Embedded”,将复制到输出目录设置为“DoNoCopy”,将自定义工具设置为“PublicResXFileCodeGenerator”,并将自定义工具名称空间设置为“Resources”。 项目本身设置为仅发布所需的文件

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

    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";
            }
        }
    }
    
    这是本地工作,但是有人知道如何让“内置”消息在发布后工作吗

    谢谢你的帮助

    致以最良好的祝愿,
    安德烈亚斯

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

    为其他错误消息fx“PropertyValueRequired”创建一个*.resx文件,并将生成操作设置为“Embedded”,将复制到输出目录设置为“Do no Copy”,将自定义工具设置为“PublicResXFileCodeGenerator”,并将自定义工具命名空间设置为“Resources”

    在我的例子中,我已经将“PropertyValueRequired”移到一个名为LocalDanish.resx的文件(仍在App_GlobalResources文件夹中),并将“MyRequiredAttributeAdapter”中的行从

    为了使“内置”错误消息正常工作,必须创建两个*.resx文件。我已经创建了WebResources.resx和WebResources.da.resx。不要更改任何内容,将其上的设置保留为默认设置(将生成操作设置为“内容”,等等)。我猜在我的案例中,网站会自动查找*.da.resx文件,因为我在我的网络配置中设置了全球化:

    <globalization uiCulture="da-DK" culture="da-DK"/>
    
    
    
    希望这对任何人都有帮助

    致以最良好的祝愿,
    安德烈亚斯

    我对原来的帖子做了一些小的补充,在我的案例中没有翻译所有的信息。 (字符串长度和无效属性值)

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

    非常感谢。这个问题让我发疯了!
    <globalization uiCulture="da-DK" culture="da-DK"/>
    
    // 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";
        }
    }
    
    // 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));