在MVC HtmlHelper中检索验证属性

时间:2016-02-19 17:29:31

标签: asp.net-mvc-4 data-annotations html-helper

我正在开发一个MVC 4 HtmlHelper(Razor)来监控字符串输入TextBox / TextArea控件时的长度。这是助手的开始。

public static MvcHtmlString CharacterCounterFor<TModel, TValue>(
    this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression,
    object htmlAttributes = null)
{
    var validationAttributes =
        helper.GetValidationAttributesFromExpression(expression);

    StringLengthAttribute stringLengthAttribute =
        validationAttributes.OfType<StringLengthAttribute>()
            .FirstOrDefault();

    if (stringLengthAttribute == null)
    {
        var propertyName = helper.GetPropertyNameFromExpression(expression);
        throw new Exception(
            string.Format(MvcResources.MissingStringLengthValidationAttribute,
                propertyName));
    }

    StringLengthAttribute stringLengthAttribute =
        validationAttributes.OfType<StringLengthAttribute>()
            .FirstOrDefault();

    /*
    ** More code...
    */
}

这里的关键代码是第一个方法语句,我使用以下HtmlHelper扩展方法GetValidationAttributesFromExpression()方法来检索所有属性ValidationAttributes

public static IEnumerable<ValidationAttribute>
    GetValidationAttributesFromExpression<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> expression)
{
    var propertyName = htmlHelper.GetPropertyNameFromExpression(expression);
    Type type = typeof (TModel);
    var prop = type.GetProperty(propertyName);
    return prop.GetCustomAttributes(true).OfType<ValidationAttribute>();
}

如果我直接在正在编辑的模型中定义我的DataAnnotations,这很有效,例如:

public class MyModel {

    [StringLength(50, ErrorMessage = "Name must not exceed {0} characters")]
    public string Name { get; set; }

    // More properties...
}

如果我更改此模型以使用MetadataType属性并使用类接口定义Data Annotations,如下所示,对GetValidationAttributesFromExpression()的调用始终返回null。

public interface IMyModel {

    [StringLength(50, ErrorMessage = "Name must not exceed {0} characters")]
    string Name { get; set; }

    // More properties...
}

[MetadataType(typeof(IMyModel))]
public class MyModel : IMyModel {

    public string Name { get; set; }

    // More properties...
}

我原本以为定义DataAnnotationAttribute的两种方法都会产生相同的表达式模型,但看起来并非如此。

任何人都可以告诉我在使用&#39; MetaDataType&#39;定义时如何访问ValidationProperties。属性?

0 个答案:

没有答案