我在 asp.net mvc 3.0 中的自定义验证有问题
我想让它做什么。
- 被设置在一个属性上(现在我只能弄清楚如何在类里面实现)
- 要足够聪明,意识到正在使用多个实例。
场景
- 文本框(id = "textbox1")
- 下拉列表(id ="ddl1")
- 文本框 (id = "textbox2") 4 下拉列表 (id = "ddl2")
下拉列表中的值是相同的。 (“天”和“分钟”)
现在用户在 textbox1 中键入 30 并在 ddl1 中选择“days”。然后,他在 textbox2 中键入 10000 并在 ddl2 中键入“days”。第一个有效,第二个无效,因为一年只有 365 天。
场景二
用户输入 texbox1 99 并在 ddl1 中选择“分钟”。这当然是无效的,应该失败。
因此,他们可以选择有效日期和无效分钟时间的任意组合。
或者两者都有效
到目前为止,我有这个
我的 View 模型
[ReminderFormat(ErrorMessage = "test")]
public class ReminderViewModel
{
public List<SelectListItem> DurationTypes { get; set; }
public DurationTypes SelectedDurationType { get; set; }
public string ReminderLength { get; set; }
}
这将在 View 模型列表中并生成我需要的数量
List<ReminderViewModel> viewModel = new List<ReminderViewModel>()
// add ReminderviewModel to this collection
查看
// do a for loop through the viewModel ( List<ReminderViewModel> )
// generate a textbox html box and drop down list for each one
数据标注
// set attribute to class for now but I want it on a property but I can't
// figure out how to get SelectedDurationType and pass it in. if I have my attribute on ReminderLength
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ReminderFormatAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
var reminderViewModel = (ReminderViewModel)value;
switch (reminderViewModel.SelectedDurationType)
{
case DurationTypes.Days:
int length = Convert.ToInt32(reminderViewModel.ReminderLength);
if (length > 30)
{
return false;
}
else
{
return true;
}
default:
throw new ArgumentOutOfRangeException();
}
}
问题一
如您所见,我在类上有注释,我宁愿在 ReminderLength 属性上有注释。
问题2
现在我只有 30 天了,所以打字比较少(我稍后会更改)。我现在发现的问题是,如果 textbox1 中有 31,这将使我的验证失败。
这是正确的。但是,如果我的 textbox2 的值为 1,它将通过验证。这也是正确的。
不正确的是它将覆盖第一个无效验证。所以现在它认为所有验证都通过并进入我的操作方法。当它应该拒绝它并返回 View 并告诉用户 textbox1 验证失败时。
最佳答案
这是我要为您的验证属性做的事情:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class ReminderFormatAttribute: ValidationAttribute, IClientValidatable
{
public string DurationProperty { get; set; }
public ReminderFormatAttribute(string durationProperty)
{
DurationProperty = durationProperty;
ErrorMessage = "{0} value doesn't work for selected duration";
}
public override string FormatErrorMessage(string propName)
{
return string.Format(ErrorMessage, propName);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var durationType = validationContext.ObjectType.GetProperty(DurationProperty).GetValue(validationContext.ObjectInstance, null);
var reminderLength = value;
// Do your switch statement on durationType here
// Here is a sample of the correct return values
switch (durationType)
{
case DurationTypes.Days:
if (reminderLength > 30)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
else
{
return null;
}
}
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "reminderformat",
};
rule.ValidationParameters["durationproperty"] = DurationProperty;
yield return rule;
}
}
现在在您的 ViewModel 中,您可以像这样注释 ReminderLength 属性:
[ReminderFormat("SelectedDurationType")]
public string ReminderLength { get; set; }
当验证取决于另一个属性的值时,我通常会这样做。 GetClientValidationRules 方法是您需要通过 jquery validate 绑定(bind)到不显眼的客户端验证的服务器端部分。 查看此链接以获取另一个 ValidationAttribute 示例:http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2
本网站上的示例还涉及编写必要的 jQuery 以绑定(bind)客户端验证
关于c# - 如何使我的自定义数据注释起作用(它在列表中,列表中的每个项目都会覆盖最后的验证测试),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4916467/