I want to make conditional validation in ASP.NET MVC Core 3.1. I have written custom validation and it works fine in server-side validation but I am unable to perform client-side validation. In my sample application, there is a Salary textbox, which is only required if the Role=Teacher is selected in the Roles dropdown. Could you please help me in the client-side validation part and here is the complete sample code.
Employee model class
public class Employee
{
public int Id { get; set; }
[Required(ErrorMessage = "Please enter name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter email")]
[EmailAddress]
public string Email { get; set; }
[Required(ErrorMessage = "Please enter role")]
[EnumDataType(typeof(Roles))]
public Roles? Role { get; set; }
[Required(ErrorMessage = "Please Enter Hire Date")]
[Display(Name = "Hire Date")]
public DateTime? HireDate { get; set; }
[RequiredIf("Role", Roles.Teacher, ErrorMessage = "Please enter salary")]
public int? Salary { get; set; }
}
Roles enum
public enum Roles
{
Student = 1,
Teacher = 2,
Assistant = 3
}
RequiredIfAttribute custom validation class
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);
}
}
Index view for the UI
@model ASPNETCoreValidations.Models.Employee
@using ASPNETCoreValidations.Models.enums
@{
ViewBag.Title = "Index";
}
<h1>Create</h1>
<h4>Business unit</h4>
<hr />
<div class="container">
<form asp-action="Index">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="col-md-6">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label asp-for="Role" class="control-label"></label>
<select asp-for="Role" class="form-control" asp-items="Html.GetEnumSelectList<Roles>()">
<option value="">Select Department</option>
</select>
<span asp-validation-for="Role" class="text-danger"></span>
</div>
<div class="col-md-6">
<label asp-for="HireDate" class="control-label"></label>
<input asp-for="HireDate" class="form-control" />
<span asp-validation-for="HireDate" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label asp-for="Salary" class="control-label"></label>
<input asp-for="Salary" class="form-control" />
<span asp-validation-for="Salary" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/js/RequiredIfValidate.js"></script>
}
Jquery for client-side validation
jQuery.validator.addMethod("requiredif",
function (value, element, param) {
// I need help here. This method never gets executed and I don't know how to implement validation here ...
// return true or false depending on the condition
});
jQuery.validator.unobtrusive.adapters.addBool("requiredif");
Index action
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(Employee employee)
{
if (ModelState.IsValid)
{
RedirectToAction("Index");
}
return View();
}
