[英]How to make my custom data annotations work( it is in a list and each item in the list overrides the last validation test)
我在asp.net mvc 3.0中的自定義驗證遇到問題
我想要它做什么。
腳本
下拉列表中的值相同。 (“天”和“分鍾”)
現在,用戶輸入textbox1 30並在ddl1中選擇“天”。 然后,他在textbox2中輸入10000,在ddl2中輸入“ days”。 第一個有效,第二個無效,因為一年只有365天。
方案2
用戶輸入texbox1 99,並在ddl1中選擇“分鍾”。 這當然是無效的,應該會失敗。
因此,他們可以在其中選擇有效日期和無效分鍾時間的任意組合。
或兩者都可能有效
所以到目前為止
我的視圖模型
[ReminderFormat(ErrorMessage = "test")]
public class ReminderViewModel
{
public List<SelectListItem> DurationTypes { get; set; }
public DurationTypes SelectedDurationType { get; set; }
public string ReminderLength { get; set; }
}
這將在視圖模型列表中,並生成我需要的模型數量
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();
}
}
問題1
如您所見,我在類上具有注釋,而在ReminderLength屬性上具有注釋。
問題2
現在我只有30天,所以輸入的時間更少了(我稍后會更改)。 我現在發現的問題是,如果textbox1中包含31,這將使我的驗證失敗。
這是對的。 但是,如果我的textbox2的值為1,它將通過驗證。 這也是正確的。
不正確的是它將覆蓋第一個無效的驗證。 因此,現在它認為所有驗證均已通過,並進入我的操作方法。 什么時候應該拒絕它,然后返回視圖並告訴用戶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綁定到簡單的客戶端驗證中。 查看此鏈接以獲取另一個ValidationAttribute示例: http : //www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2
該站點上的示例還涉及編寫必要的jQuery以配合客戶端驗證
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.