必需的数据注释未被翻译

时间:2015-04-20 09:01:05

标签: c# asp.net asp.net-mvc validation data-annotations

我们面临着必需属性本地化的奇怪错误。

我们有以下代码:

    public class AnswersGroupViewModel
    {
        public int IDAnswerGroup { get; set; }
        public int IDEvaluator { get; set; }
        public List<AnswersViewModel> Answers { get; set; }
    }

    public class AnswersViewModel
    {        
        public string Text{ get; set; }      
        [Required(ErrorMessageResourceName = "RequiredMessage", ErrorMessageResourceType = typeof(Resources.Language))]
        public int IDAnswer{ get; set; }
    }

问题是“RequiredMessage”的正确翻译没有从资源文件中获取,尽管它存在(我们在西班牙语和俄语资源文件上都有RequiredMessage)。

像Display这样的属性正在工作和被翻译,但似乎是必需属性的问题。

以下是一个示例图片:

Labels are translated to russian, but required message is in spanish

错误显示为@ Html.ValidationMessage

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:8)

我首先要在web.config中设置全球化元素

<system.web>
  <globalization enableClientBasedCulture="true" culture="auto" uiCulture="auto"/>

接下来,我会检查您在Controller中获得的文化(在数据库中登录或传递到@ViewBag的视图

culture = CultureInfo.InstalledUICulture.IetfLanguageTag;
if (HttpContext.Current != null && HttpContext.Current.Request.UserLanguages != null)
{
    culture = Request.UserLanguages[0];     
}

确认用于标识Culture的值是标题使用的值

跟进

您正在使用全球化标头检查用户语言,但是在浏览器中手动设置用户语言。

尝试2种方法:

1)使用Javascript在浏览器中设置用户语言:

<script type="text/javascript"> 
     Globalize.culture("@ViewBag.Culture");
</script>

或者如果文化是在Javascript(vs C#)中设置的

<script type="text/javascript"> 
     Globalize.culture(culturevariable);
</script>

2) ParameterisedRequiredAttribute

public class ParameterisedRequiredAttribute : RequiredAttribute
{
    private string[] _replacements { get; set; }

    public ParameterisedRequiredAttribute(params string[] replacements)
    {
        _replacements = replacements;

        ErrorMessageResourceName = ErrorMessagesErrors.SpecificFieldRequired;
        ErrorMessageResourceType = typeof(ErrorMessages);
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(ErrorMessageString, (object[])_replacements);
    }
}

如果您手动设置语言,第一种方法似乎是更好的解决方案。简而言之,每次用户更改语言模式时都必须重新设置注释。

另一件需要考虑的事情是,您当前设置语言(通过标题)的方式可能是您的最佳解决方案。虽然这很难测试,因为您需要一个具有专用语言的客户端,但这是您的用户最佳区分方式(按标题)。

答案 1 :(得分:1)

确保您的当前线程上下文已更新,以便根据Web客户端的Request标头使用正确的CultureInfo。如果您已定义<globalization ..>标记,则此自动。否则,添加过滤器以拦截请求并执行更新。

var cultureName = "de-DE"; // get this from request headers
var ci = new CultureInfo(cultureName);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;

另见From where CultureInfo.CurrentCulture reads culture

答案 2 :(得分:1)

我创建了一个示例应用,以便重现您的问题。它适用于我,所以我会给你我当前的设置。

我有一个引用库程序集资源的Web应用程序项目。

我在资源项目中有2个resx文件(language.resx和language.fr.resx)。两个文件都具有相同的属性:

  • 构建操作:嵌入式资源,
  • 自定义工具:PublicResXFileCodeGenerator,
  • 自定义工具命名空间:MyResources

ViewModel AnswersViewModel具有IDAnswer属性,其属性如下:

[Required(ErrorMessageResourceName = "RequiredMessage", 
          ErrorMessageResourceType = typeof(MyResources.Language))]

我已将名称空间MyResource添加到View文件夹中的web.config文件中,并通过添加

更新了主web.config的system.web部分
<globalization enableClientBasedCulture="true" culture="auto" uiCulture="auto"/>

我希望它会有所帮助。