11

このようなモデルがあるとします

public class User
{
    [Required]
    [StringLength(14, ErrorMessage = "Can only be 14 characters long")]
    public string UserName;

}

次のようなHtmlヘルパーを作成したい:

@Html.ValidatableEditorFor(m => m.UserName)

次のように、jQuery Vaidation プラグインが検証できる正しい形式のテキスト フィールドを吐き出すようにします。

   <input type="text" class="required" maxlength="14" />

私の調査によると、MetaDataModel 内のすべてのデータ注釈を反復処理して、どれが jQuery Validation に適用できるかを確認する方法はないようです。

疑似コードでの動作をどのように想像するか:

    var tag = new TagBuilder("input");
    tag.mergeAttribute("type", "text");
    foreach(var attribute in metadata.attributes)
    {
       CheckForValidatableAttribute(attribute, tag);
    }

...
    private void CheckForValidatableAttribute(DataAnnotation attribute, TagBuilder tag)
    {
        switch(attribute.type)
       {
          case Required:
             tag.addClass("required");
             break;
          case StringLength
             tag.mergeAttribute("maxlength", attribute.value)
             break;
       }
    }

このようなヘルパーを実現するにはどうすればよいでしょうか? 検証リテラルを複製する必要がないように、データ注釈で機能するようにします。

たとえば、TextEditorFor などの現在の Html ヘルパーは、有効な属性を出力フィールドに追加します。どのようにこれを行い、どうすれば独自の実装を作成できますか?

乾杯

4

2 に答える 2

6

次の単純な条件を使用できます。

if(attribute.Type is ValidationAttribute)
{
   string className = attribute.Type.Name.Replace("Attribute", "").ToLower();
}

アップデート

Html ヘルパーを定義します。

public static MvcHtmlString ValidationEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> expression)
{
    ....
}

このヘルパー メソッドを作成します。

private static string GetPropertyNameFromExpression<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
    MemberExpression memberExpression = expression.Body as MemberExpression;
    if (memberExpression == null)
        throw new InvalidOperationException("Not a memberExpression");

    if (!(memberExpression.Member is PropertyInfo))
        throw new InvalidOperationException("Not a property");

    return memberExpression.Member.Name;
}

これを次で使用しますValidationEditorFor

var propertyName = GetPropertyNameFromExpression(htmlHelper, expression);
var propertyType = typeof(TModel).GetProperties().Where(x=>x.Name == propertyName).First().PropertyType;
var attributes = propertyType.GetCustomAttributes(true).OfType<ValidationAttribute>();

これで属性を確認できるようになりました...残りは簡単です。

于 2012-04-30T10:24:04.317 に答える
2

わずかに変更され、ヘルパーに抽出されます。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace Payntbrush.Infrastructure.Web.Mvc
{
    public static class ReflectionHelper
    {
        public static IEnumerable<ValidationAttribute> GetAttributes<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
        {
            Type type = typeof(TModel);
            var prop = type.GetProperty(GetPropertyNameFromExpression(expression));
            return prop.GetCustomAttributes(true).OfType<ValidationAttribute>();
        }


        private static string GetPropertyNameFromExpression<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
        {
            var memberExpression = expression.Body as MemberExpression;
            if (memberExpression == null)
                throw new InvalidOperationException("Not a memberExpression");

            if (!(memberExpression.Member is PropertyInfo))
                throw new InvalidOperationException("Not a property");

            return memberExpression.Member.Name;
        }
    }
}
于 2012-04-30T11:55:08.550 に答える