Добавить правило проверки для свойства модели динамически в asp.net mvc2
Информация / правила проверки одного свойства модели доступны в других свойствах того же объекта модели. Я должен проверить значения свойств, используя другие значения свойств.
Модельный класс:-
[FormatValidtion("Value", "Format", "MinLength", "MaxLength", ErrorMessage = "Please enter correct format")]
public class Sample
{
#region ModelProperties
public string Id { get; set; }
[Required(ErrorMessage = "Please Enter Value")]
public string Value { get; set; }
public string Format { get; set; }
public string MinLength { get; set; }
public string MaxLength { get; set; }
#endregion
}
Объект модели выглядит как выше. Здесь я должен проверить свойство Value, используя
Формат (проверка Fomart, как электронная почта, телефон и дата)
Свойства MinLength, MaxLength (проверка диапазона).
Я знаю, что мы можем сделать это с помощью пользовательских проверок, таких как
- Создайте пользовательский класс, сохраняя ValidationAttribute в качестве базы
- Передайте все эти свойства (значение, формат, минимальная длина и максимальная длина)
- Записать регистр переключателя со свойством Format.
- Подтвердите форматирование с помощью Regex и выполните ручную проверку диапазона или динамическую проверку Regex.
РЕДАКТИРОВАТЬ:- Добавлен пользовательский код класса проверки здесь
Пользовательский класс проверки:
[AttributeUsage(AttributeTargets.Class)]
public class FormatValidtion : ValidationAttribute
{
public String Value { get; set; }
public String Format { get; set; }
public String MinLength { get; set; }
public String MaxLength { get; set; }
public FormatValidtion(String value, String format, String minLength, String maxLength)
{
Value = value;
Format = format;
MinLength = minLength;
MaxLength = maxLength;
}
public override Boolean IsValid(Object value)
{
Type objectType = value.GetType();
PropertyInfo[] neededProperties =
objectType.GetProperties()
.Where(p => p.Name == Value || p.Name == Format || p.Name == MinLength || p.Name == MaxLength)
.ToArray();
if (neededProperties.Count() != 4)
{
throw new ApplicationException("PropertiesMatchAttribute error on " + objectType.Name);
}
Boolean isMatched = true;
switch (Convert.ToString(neededProperties[1].GetValue(value, null)))
{
case "Alpha":
Regex regExAlpha = new Regex(@"/^[A-Za-z]+$/");
if (!regExAlpha.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
{
isMatched = false;
}
break;
case "Number":
Regex regExNumber = new Regex(@"/^[0-9]+$/");
if (!regExNumber.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
{
isMatched = false;
}
break;
case "AlphaNum":
Regex regExAlphaNum = new Regex(@"/^[a-zA-Z][a-zA-Z0-9]+$/");
if (!regExAlphaNum.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
{
isMatched = false;
}
break;
default:
isMatched = false;
break;
}
return isMatched;
}
}
Это работает правильно на уровне класса и показывает сообщения проверки через сводку проверки. Но я хочу изменить приведенный выше код, чтобы сделать следующие вещи.
- Проверка должна происходить на уровне свойства или как-то, как нужно показать сообщение об ошибке на уровне свойства (используя вспомогательный класс validationMessage).
- Необходимо предоставить конкретные сообщения об ошибках для каждой проверки, кроме общего сообщения об ошибке.
- Проверка диапазона должна произойти.
Кто-нибудь может высказать некоторые мысли по этому поводу?
2 ответа
Вы можете использовать интерфейс IValidatableObject. При правильной реализации вы можете показать уровень свойств и пользовательские сообщения об ошибках.
Вот вопрос для дальнейшего чтения
Я сделал с помощью следующего кода.
Модельный класс:-
[FormatValidtion("Value", "Format", "MinLength", "MaxLength")]
public class Sample
{
#region ModelProperties
public string Id { get; set; }
[Required(ErrorMessage = "Please Enter Value")]
public string Value { get; set; }
public string Format { get; set; }
public string MinLength { get; set; }
public string MaxLength { get; set; }
#endregion
}
Пользовательский класс проверки:-
[AttributeUsage(AttributeTargets.Class)]
public class FormatValidtion : ValidationAttribute
{
public string Value { get; set; }
public string Format { get; set; }
public string MinLength { get; set; }
public string MaxLength { get; set; }
public string Format1 { get; set; }
public string Value1 { get { return Value; } }
public FormatValidtion(String value, String format, String minLength, String maxLength)
{
Value = value;
Format = format;
MinLength = minLength;
MaxLength = maxLength;
}
public override Boolean IsValid(Object value)
{
Type objectType = value.GetType();
PropertyInfo[] neededProperties =
objectType.GetProperties()
.Where(p => p.Name == Value || p.Name == Format || p.Name == MinLength || p.Name == MaxLength)
.ToArray();
if (neededProperties.Count() != 4)
{
throw new ApplicationException("PropertiesMatchAttribute error on " + objectType.Name);
}
Boolean isMatched = true;
this.Format1 = Convert.ToString(neededProperties[1].GetValue(value, null));
switch (Convert.ToString(neededProperties[1].GetValue(value, null)))
{
case "Alpha":
Regex regExAlpha = new Regex(@"/^[A-Za-z]+$/");
if (!regExAlpha.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
{
isMatched = IsValidLength(Convert.ToString(neededProperties[0].GetValue(value, null)).Length, Convert.ToInt32(neededProperties[2].GetValue(value, null)), Convert.ToInt32(neededProperties[3].GetValue(value, null)));
}
break;
case "Number":
Regex regExNumber = new Regex(@"/^[0-9]+$/");
if (!regExNumber.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
{
isMatched = IsValidLength(Convert.ToString(neededProperties[0].GetValue(value, null)).Length, Convert.ToInt32(neededProperties[2].GetValue(value, null)), Convert.ToInt32(neededProperties[3].GetValue(value, null)));
}
break;
case "AlphaNum":
Regex regExAlphaNum = new Regex(@"/^[a-zA-Z][a-zA-Z0-9]+$/");
if (!regExAlphaNum.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
{
isMatched = IsValidLength(Convert.ToString(neededProperties[0].GetValue(value, null)).Length, Convert.ToInt32(neededProperties[2].GetValue(value, null)), Convert.ToInt32(neededProperties[3].GetValue(value, null)));
}
break;
default:
isMatched = false;
break;
}
return isMatched;
}
/// range validation
public bool IsValidLength(int valueLenght, int minLenght, int maxLenght)
{
if (valueLenght >= minLenght && valueLenght <= maxLenght)
return true;
return false;
}
}
Класс адаптера валидации:-
public class FormatValidtionAdapter : DataAnnotationsModelValidator<FormatValidtion>
{
public FormatValidtionAdapter(ModelMetadata metadata, ControllerContext context, FormatValidtion attribute)
: base(metadata, context, attribute)
{
}
// To Provide Error messages dynamically depends on format.
public override IEnumerable<ModelValidationResult> Validate(object container)
{
string ErrorMessage = null;
if (!Attribute.IsValid(Metadata.Model))
{
switch (Attribute.Format1)
{
case "Alpha":
ErrorMessage = "Please enter alphabets only";
break;
case "Number":
ErrorMessage = "Please enter numbers only";
break;
case "AlphaNum":
ErrorMessage = "Please enter alphanumeric only";
break;
default:
break;
}
yield return new ModelValidationResult
{
Message = ErrorMessage,
MemberName = Attribute.Value1
};
}
}
}
Global.aspx.cs:-
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(FormatValidtion), typeof(FormatValidtionAdapter));
}