ASP.NET MVC Conditional validation
How to use data annotations to do a conditional validation on model?
For example, lets say we have the following model (Person and Senior):
public class Person
{
[Required(ErrorMessage = "*")]
public string Name
{
get;
set;
}
public bool IsSenior
{
get;
set;
}
public Senior Senior
{
get;
set;
}
}
public class Senior
{
[Required(ErrorMessage = "*")]//this should be conditional validation, based on the "IsSenior" value
public string Description
{
get;
set;
}
}
And the following view:
<%= Html.EditorFor(m => m.Name)%>
<%= Html.ValidationMessageFor(m => m.Name)%>
<%= Html.CheckBoxFor(m => m.IsSenior)%>
<%= Html.ValidationMessageFor(m => m.IsSenior)%>
<%= Html.CheckBoxFor(m => m.Senior.Description)%>
<%= Html.ValidationMessageFor(m => m.Senior.Description)%>
I would like to be the "Senior.Description" property conditional required field based on the selection of the "IsSenior" propery (true -> required). How to implement conditional validation in ASP.NET MVC 2 with data annotations?
there's a much better way to add conditional validation rules in MVC3. Have your model inherit IValidatableObject and implement the Validate method:
public class Person : IValidatableObject
{
public string Name { get; set; }
public bool IsSenior { get; set; }
public Senior Senior { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (IsSenior && string.IsNullOrEmpty(Senior.Description))
yield return new ValidationResult("Description must be supplied.");
}
}
see more of a description at http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx
I have solved this by handling the "ModelState" dictionary, which is contained by the controller. The ModelState dictionary includes all the members that have to be validated.
Here is the solution:
If you need to implement a conditional validation based on some field (eg if A=true, then B is required), while maintaining property level error messaging (this is not true for the custom validators that are on object level) you can achieve this by handling "ModelState", by simply removing unwanted validations from it.
...In some class...
public bool PropertyThatRequiredAnotherFieldToBeFilled
{
get;
set;
}
[Required(ErrorMessage = "*")]
public string DepentedProperty
{
get;
set;
}
...class continues...
...In some controller action ...
if (!PropertyThatRequiredAnotherFieldToBeFilled)
{
this.ModelState.Remove("DepentedProperty");
}
...
With this we achieve conditional validation, while leaving everything else the same.
UPDATE:
This is my final implementation: I have used an interface on the model and the action attribute that validates the model which implements the said interface. Interface prescribes the Validate(ModelStateDictionary modelState) method. The attribute on action just calls the Validate(modelState) on IValidatorSomething.
I did not want to complicate this answer, so I did not mention the final implementation details (which, at the end, matter in production code).
I had the same problem yesterday but I did it in a very clean way which works for both client side and server side validation.
Condition: Based on the value of other property in the model, you want to make another property required. Here is the code
public class RequiredIfAttribute : RequiredAttribute
{
private String PropertyName { get; set; }
private Object DesiredValue { get; set; }
public RequiredIfAttribute(String propertyName, Object desiredvalue)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
Object instance = context.ObjectInstance;
Type type = instance.GetType();
Object proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if (proprtyvalue.ToString() == DesiredValue.ToString())
{
ValidationResult result = base.IsValid(value, context);
return result;
}
return ValidationResult.Success;
}
}
Here PropertyName is the property on which you want to make your condition DesiredValue is the particular value of the PropertyName (property) for which your other property has to be validated for required
Say you have the following
public class User
{
public UserType UserType { get; set; }
[RequiredIf("UserType", UserType.Admin, ErrorMessageResourceName = "PasswordRequired", ErrorMessageResourceType = typeof(ResourceString))]
public string Password
{
get;
set;
}
}
At last but not the least , register adapter for your attribute so that it can do client side validation (I put it in global.asax, Application_Start)
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute),typeof(RequiredAttributeAdapter));
链接地址: http://www.djcxy.com/p/67990.html
上一篇: 通过jquery ajax在Web Api中显示无效的ModelState
下一篇: ASP.NET MVC有条件验证