ASP.NET MVC Conditional validation
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 (e.g. 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).
Set Required Field Validation based on condition in ASP.NET MVC
You can add custom validation logic by implementing IValidatableObject
on the ViewModel.
public class MyViewModelThatMixesTwoUsecases : IValidatableObject {
public string EmployeeCode { get; set; }
public bool IsCreateUsecase { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (IsCreateUsecase && string.IsNullOrWhiteSpace(EmployeeCode)) {
yield return new ValidationResult(
"EmployeeCode is required for create usecase",
new[] {"EmployeeCode"}
);
}
}
}
In the controller, test whether your model is valid by calling ModelState.IsValid
.
Conditional client side validation in ASP.NET MVC Core 3.1
According to your description, I suggest you could add a property in the RequiredIfAttribute AddValidation attribute to add the role to the input salary.
Then I suggest you could try to use below validation unobtrusive scripts:
RequiredIfAttribute :
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
public string PropertyName { get; set; }
public object Value { get; set; }
public RequiredIfAttribute(string propertyName, object value, string errorMessage = "")
{
PropertyName = propertyName;
ErrorMessage = errorMessage;
Value = value;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var instance = validationContext.ObjectInstance;
var type = instance.GetType();
var proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if (proprtyvalue != null)
{
if (proprtyvalue.ToString() == Value.ToString() && value == null)
{
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
context.Attributes.Add("data-val", "true");
context.Attributes.Add("data-val-country", ErrorMessage);
context.Attributes.Add("data-val-country-role", Value.ToString());
}
}
Scripts:
@section Scripts{
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>
<script>
$.validator.addMethod('country', function (value, element, params) {
var genre = $(params[0]).val(), role = params[1], salar = value;
var selecttest = $("#Role option:selected").text();
if (selecttest == role) {
if (value.length == 0) {
console.log("selecttest == role value = null");
return false;
} else {
console.log("selecttest == role value != null");
return true;
}
} else {
console.log("selecttest != role");
return true;
}
});
$.validator.unobtrusive.adapters.add('country', ['role'], function (options) {
var element = $(options.form).find('select#Salary')[0];
options.rules['country'] = [element, options.params['role']];
options.messages['country'] = options.message;
});
</script>
}
Result:
Conditional validation on model in MVC
If you're on MVC3/.NET4, you can use IValidatableObject
which exists specifically for such purposes.
Quoting ScottGu,
...The IValidatableObject interface enables you to perform model-level
validation, and enables you to provide validation error messages
specific to the state of the overall model....
You model would look like
public class MyViewModel : IValidatableObject
{
public long? Id { get; set; }
public decimal? ProposedCost { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Id != null && ProposedCost == 0) {
yield return new ValidationResult("ProposedCost must be provided.");
}
}
}
and then in the controller,
[HttpPost]
public ActionResult Submit(MyViewModel model)
{
if (!ModelState.IsValid) {
//failed - report an error, redirect to action etc
}
//succeeded - save to database etc
}
Otherwise, the most clean solution would be to use view models - UpdateViewModel
where the property is required, and CreateViewModel
where it's not required.
Conditional validation in MVC.NET Core (RequiredIf)
Found an answer
Changed
if (proprtyvalue.ToString() == DesiredValue.ToString() && value == null)
to
if (proprtyvalue.ToString() == DesiredValue.ToString() && value.ToString() == "N/A")
Conditional Validation for ViewModel Fields on ASP MVC
I seem to have found the solution:
if(EmailTurnedOff)
{
this.ViewData.ModelState.Remove("Email");
}
Then when I call ModelState.IsValid it will give me the correct answer
Related Topics
Fire and Forget Async Method in ASP.NET MVC
Where Is the Application.Doevents() in Wpf
Add New Item in Existing Array in C#.Net
How to Change Menu Hover Color
Convert String[] to Int[] in One Line of Code Using Linq
Difference Between Observablecollection and Bindinglist
How to Check Whether a String Is a Valid Http Url
Reading PDF Content Using Itextsharp in C#
Best Practices for Exception Management in Java or C#
Getting Value from Appsettings.JSON in .Net Core
How to Set Processor Affinity to a Thread or a Task in .Net
Puzzling Enumerable.Cast Invalidcastexception
How to Create a Self-Signed Certificate Using C#
Getting Image Dimensions Without Reading the Entire File
How to Tell a Lambda Function to Capture a Copy Instead of a Reference in C#