我创建了以下自定义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数据库中的一组选项生成的资源类。上述两个资源属性的生成代码的简化版本是:
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”分别是 minDate 和 maxDate 参数值进入DateRangeAttribute的构造函数。
如果我尝试
[DateRange(Resources.PropMinimumDate, Resources.PropMaximumDate, "Please enter a date between {0} and {1}")]
我收到编译错误:
属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式
有没有办法完成这项任务,还是我尝试了不可能的事情?
答案 0 :(得分: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))]
答案 1 :(得分: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
类。