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}")]

资源是基于存储在 SQL 数据库中的一组选项生成的资源类。上述两个资源属性的生成代码的简化版本是:

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.MinimumDate映射到PropMinimumDate并返回值“12/15/2010”。

我不知道如何自己手动进行编程飞跃,以便我可以将两个日期值传递到我的自定义 ValidatorAttribute 中。按照目前的编码,“PropMinimumDate”“PropMaximumDate”是传递给 DateRangeAttribute 构造函数的minDatemaxDate参数值(分别)。

如果我尝试

[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

你不是在尝试不可能的事情,但你将不得不稍微解决这个限制。所以,为了符合编译器的要求,我们有两个选择,第一个是最理想的,改变生成的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 回答