MVC3修改模型验证元数据和错误消息

时间:2011-10-30 00:43:07

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

我需要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属性,但我不能。

有没有办法做到这一点?如果有,它可以为我节省生命:)

3 个答案:

答案 0 :(得分:1)

您可以使用resource files to do localization

添加资源文件(您可以通过Visual Studio使用“添加新项目”向导 - 将其称为MyResourcesType.resx)到项目中。然后添加如下验证消息:

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

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

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

我有一个解决方法来创建我的自定义@ 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));
    }
}
}

我的观点是:

@using MyCMS.Localization; @using 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>

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

再次感谢大家......