4

次のカスタムValidationAttributeを作成しました。

public class DateRangeAttribute : ValidationAttribute, IClientValidatable {
  public DateTime MinimumDate = new DateTime(1901, 1, 1);
  public DateTime MaximumDate = new DateTime(2099, 12, 31);

   public DateRangeAttribute(string minDate, string maxDate, string errorMessage) {
     MinimumDate = DateTime.Parse(minDate);
     MaximumDate = DateTime.Parse(maxDate);
     ErrorMessage = string.Format(errorMessage, MinimumDate.ToString("MM/dd/yyyy"), MaximumDate.ToString("MM/dd/yyyy"));
   }
}

次のように、MVC4ビューモデルで使用したいと思います。

[DateRange(Resources.MinimumDate, Resources.MaximumDate, "Please enter a date between {0} and {1}")]

Resourcesは、SQLデータベースに格納されている一連のオプションに基づいて生成されたリソースクラスです。上記の2つのリソースプロパティに対して生成されたコードの簡略化されたバージョンは次のとおりです。

public class Resources {
  public const string MinimumDate = "PropMinimumDate";
  public static string PropMinimumDate
  {
     get { return "12/15/2010" } 
  }
  public const string MaximumDate = "PropMaximumDate";
  public static string PropMaximumDate
  {
     get { return "12/15/2012" } 
  }
}

それがどのように機能するかはわかりませんが、ValidationAttributesのリソースの一般的な使用法は、Resources.MinimumDatePropMinimumDateに自動的にマップし、値「12/15/2010」を返すことを理解しています。

私が理解できないのは、2つの日付値をカスタムValidatorAttributeに渡すことができるように、そのプログラムを手動で飛躍させる方法です。現在コーディングされているように、「PropMinimumDate」「PropMaximumDate」は、 DateRangeAttributeのコンストラクターに(それぞれ)渡されるminDateおよびmaxDateパラメーター値です。

やってみたら

[DateRange(Resources.PropMinimumDate, Resources.PropMaximumDate, "Please enter a date between {0} and {1}")]

コンパイルエラーが発生します:

属性の引数は、定数式、typeof式、または属性パラメータータイプの配列作成式である必要があります。

このタスクを達成する方法はありますか、それとも私は不可能を試みていますか?

4

2 に答える 2

1

Typeリソースクラスのを引数として取り、リフレクションを使用してプロパティ値を取得する必要があります。

public class DateRangeAttribute : ValidationAttribute, IClientValidatable {
  public DateTime MinimumDate = new DateTime(1901, 1, 1);
  public DateTime MaximumDate = new DateTime(2099, 12, 31);
  private Type _resourceType;

   public DateRangeAttribute(string minDate, string maxDate, string errorMessage, Type resourceType) {
     _resourceType = resourceType;
     var minDateProp = _resourceType.GetProperty(minDate, 
                             BindingFlags.Static | BindingFlags.Public);
     var minDateValue = (string) minDateProp.GetValue((object) null, (object[]) null));
     MinimumDate = DateTime.Parse(minDateValue);

     // similarly get the value for MaxDate

     ErrorMessage = string.Format(errorMessage, 
            MinimumDate.ToString("MM/dd/yyyy"), MaximumDate.ToString("MM/dd/yyyy"));         
   }
}

例えば

[DateRange(Resources.MinimumDate, Resources.MaximumDate, "Please enter a date between {0} and {1}", typeof(Resources))]
于 2012-10-17T04:04:20.997 に答える
0

あなたは不可能を試みているわけではありませんが、制限を少しだけ回避する必要があります。したがって、コンパイラに準拠するには2つのオプションがあり、最初のオプションが最も理想的です。生成されたResourcesクラスを変更します。

public class Resources {
  public const string PropMinimumDate = "12/15/2010";
  public const string PropMaximumDate = "12/15/2012";
}

それができない場合は、別のルートに移動します。装飾されたプロパティが存在するクラスを変更し、そのconstようにいくつかのフィールドを追加しましょう。

public class EntityClass
{
    private const string MinimumDate = "12/15/2010";
    private const string MaximumDate = "12/15/2012";

    [DateRange(MinimumDate, MaximumDate, "Please enter a date between {0} and {1}")]
}

ただし、エンティティクラスをコードで生成できない限り、最後のオプションはデータベースから値を取得する必要性に違反します。だから、うまくいけば、Resourcesクラスを変更することができます。

于 2012-10-17T01:02:00.117 に答える