I need to implement custom Model Validator in .NET Core project. I need to do complex validation so I am avoiding Attribute validation. I used
public class UserModel : IValidatableObject {
public int UserId { get; set; }
public string UserName { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
}
}
But I need to separate Validation logic from Model So I found this in ASP.NET MVC -
public class ProjectModelValidatorProvider : ModelValidatorProvider {
public override IEnumerable<ModelValidator>
GetValidators(ModelMetadata metadata, ControllerContext context) {
if (metadata.ModelType == typeof(User))
yield return new UserModelValidator(metadata, context);
}
}
public class UserModelValidator : ModelValidator {
public UserModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
: base(metadata, controllerContext) { }
public override IEnumerable<ModelValidationResult> Validate(object container) {
var model = (User)Metadata.Model;
if (string.IsNullOrEmpty(model.Login))
yield return new ModelValidationResult {
MemberName = "Login",
Message = "Please specify Login"
};
}
}
// register your Provider
ModelValidatorProviders.Providers.Add(new ProjectModelValidatorProvider());
With the help of ModelValidatorProvider and ModelValidator I achieved it. But how to achieve this in .NET Core such that with ModelState.IsValid I will be able to validate the model ?
In ASP.NET Core , you could customize a class that inherits IModelValidatorProvider interface like below :
public class CustomModelValidatorProvider : IModelValidatorProvider
{
public void CreateValidators(ModelValidatorProviderContext context)
{
if (context.ModelMetadata.ContainerType == typeof(User))
{
context.Results.Add(new ValidatorItem
{
Validator = new UserModelValidator(),
IsReusable = true
});
}
}
}
public class UserModelValidator : IModelValidator
{
private static readonly object _emptyValidationContextInstance = new object();
public IEnumerable<ModelValidationResult> Validate(ModelValidationContext validationContext)
{
var validationResults = new List<ModelValidationResult>();
if (validationContext.ModelMetadata.Name == "FirstName" && validationContext.Model == null)
{
var validationResult = new ModelValidationResult("", "FirstName is required");
validationResults.Add(validationResult);
}
return validationResults;
}
}
You could also add partial keyword in your model to separate Validation logic from Model , refer to following code:
public partial class User
{
public int Id { get; set; }
public string Gender { get; set; }
[MaxLength(10)]
public string FirstName { get; set; }
[MaxLength(30)]
public string LastName { get; set; }
[EmailAddress]
public string Email { get; set; }
public List<UserGroups> UserGroups { get; set; }
public List<Referal> Referals { get; set; }
}
public partial class User : IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (string.IsNullOrEmpty(FirstName))
{
yield return new ValidationResult("FirstName is Required", new[] { "FirstName" });
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With