【问题标题】:MVC3 modifying model validation metadata and error messagesMVC3 修改模型验证元数据和错误消息
【发布时间】:2011-12-18 01:29:35
【问题描述】:

我需要 ASP.NET MVC3 模型验证逻辑的解决方案。我有一个自定义本地化解决方案,我正在通过一种翻译方法传递所有字符串,类似于:

    @Localizer.Translate("Hello world!") 

注意:我不确定,但我认为这种方法来自 QT 本地化逻辑。 WordPress 也在使用 smillar 技术。

当我尝试将此解决方案应用于模型验证属性时:

    [Required(ErrorMessage = Localizer.Translate( "Please enter detail text!"))]
    [DisplayName(Localizer.Translate( "Detail"))]
    public string Details { get; set; }

编译器给了我这个错误:

错误1 属性参数必须是属性参数类型的常量表达式、typeof表达式或数组创建表达式...

所以,我尝试即时修改错误消息和 DisplayName 属性,但我做不到。

有没有办法做到这一点?如果有的话,对我来说可能是救命稻草:)

【问题讨论】:

    标签: c# asp.net asp.net-mvc-3 localization model-validation


    【解决方案1】:

    您可以使用resource files to do localization

    向您的项目添加一个资源文件(您可以通过 Visual Studio 使用“添加新项目”向导 - 我们称之为 MyResourcesType.resx)。然后像这样添加您的验证消息:

    [Required(
        ErrorMessageResourceType = typeof(MyResourcesType),
        ErrorMessageResourceName = "MyMessageIdOnTheResourcesFile")]
    

    从现在开始更改语言只是添加新资源文件的问题。检查this question's first answer

    顺便说一下,不要使用DisplayNameAttribute,而是使用System.ComponentModel.DataAnnotations命名空间中的DisplayAttribute。这是 MVC 使用的属性,您也可以对其进行本地化:

    [Display(
        ResourceType = typeof(MyResourcesType),
        Name = "MyPropertyIdOnResourcesFile_Name",
        ShortName = "MyPropertyIdOnResourcesFile_ShortName",
        Description = "MyPropertyIdOnResourcesFile_Description")]
    

    【讨论】:

    • 我不只是说您可以为此使用资源文件;这就是您应该在 .NET 中处理本地化的方式。
    【解决方案2】:

    属性的工作方式是将它们静态编译到代码中。因此,在使用属性时,您不能拥有任何动态功能。

    Jota 的回答是推荐的做事方式,但是如果您决定使用自己的解决方案,则可以创建自己的属性,并在该属性中添加查找消息的代码。

    【讨论】:

      【解决方案3】:

      我有一个解决方法来创建我的自定义 @Html.LabelFor() 和 @html.DescriptionFor() 助手。

      我的助手:

      namespace MyCMS.Helpers
      {
      public static class Html
      {
          public static MvcHtmlString DescriptionFor<TModel, TValue>(
              this HtmlHelper<TModel> self, 
              Expression<Func<TModel, TValue>> expression)
          {
              var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
              var description = Localizer.Translate(metadata.Description);
      
              return MvcHtmlString.Create(string.Format(@"<span class=""help-block"">{0}</span>", description));
          }
      
          public static MvcHtmlString LabelFor<TModel, TValue>(
              this HtmlHelper<TModel> self, 
              Expression<Func<TModel, TValue>> expression, 
              bool showToolTip
          )
          {
              var metadata = ModelMetadata.FromLambdaExpression(expression, self.ViewData);
              var name = Localizer.Translate(metadata.DisplayName);
      
              return MvcHtmlString.Create(string.Format(@"<label for=""{0}"">{1}</label>", metadata.PropertyName, name));
          }
      }
      }
      

      我的看法是:

      @使用 MyCMS.Localization; @使用 MyCMS.Helpers;

          <div class="clearfix ">
              @Html.LabelFor(model => model.RecordDetails.TitleAlternative)
              <div class="input">
                  @Html.TextBoxFor(model => model.RecordDetails.TitleAlternative, new { @class = "xxlarge" })
                  @Html.ValidationMessageFor(model => model.RecordDetails.TitleAlternative)
                  @Html.DescriptionFor(model => model.RecordDetails.TitleAlternative)
              </div>
          </div>
      

      我可以使用我的本地化方法:)

      再次感谢大家...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-15
        • 2016-08-06
        • 2011-09-23
        • 1970-01-01
        • 2011-08-08
        • 1970-01-01
        相关资源
        最近更新 更多