استفاده از Fluent Validation در برنامههای ASP.NET Core - قسمت اول - معرفی، نصب و تعریف قواعد اعتبارسنجی
نویسنده: وحید نصیری
تاریخ: ۱۳۹۹/۰۳/۳۰ ۱۲:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
dotnet add package FluentValidation.AspNetCore
using System.ComponentModel.DataAnnotations;
namespace FluentValidationSample.Models
{
public class RegisterModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[DataType(DataType.EmailAddress)]
[Display(Name = "Email")]
[EmailAddress]
public string Email { get; set; }
[Range(18, 60)]
[Display(Name = "Age")]
public int Age { get; set; }
}
} using FluentValidation;
namespace FluentValidationSample.Models
{
public class RegisterModelValidator : AbstractValidator<RegisterModel>
{
public RegisterModelValidator()
{
RuleFor(x => x.UserName).NotNull();
RuleFor(x => x.Password).NotNull().Length(6, 100);
RuleFor(x => x.ConfirmPassword).Equal(x => x.Password);
RuleFor(x => x.Email).EmailAddress();
RuleFor(x => x.Age).InclusiveBetween(18, 60);
}
}
} using System.ComponentModel.DataAnnotations;
namespace FluentValidationSample.Models
{
public class RegisterModel
{
[Display(Name = "User name")]
public string UserName { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
public string ConfirmPassword { get; set; }
[DataType(DataType.EmailAddress)]
[Display(Name = "Email")]
public string Email { get; set; }
[Display(Name = "Age")]
public int Age { get; set; }
}
} using FluentValidation;
namespace FluentValidationSample.Models
{
public class RegisterModelValidator : AbstractValidator<RegisterModel>
{
public RegisterModelValidator()
{
RuleFor(x => x.UserName)
.NotNull()
.WithMessage("Your first name is required.")
.MaximumLength(20)
.WithMessage("Your first name is too long!")
.MinimumLength(3)
.WithMessage(registerModel => $"Your first name `{registerModel.UserName}` is too short!");
RuleFor(x => x.Password)
.NotNull()
.WithMessage("Your password is required.")
.Length(6, 100);
RuleFor(x => x.ConfirmPassword)
.NotNull()
.WithMessage("Your confirmation password is required.")
.Equal(x => x.Password)
.WithMessage("The password and confirmation password do not match.");
RuleFor(x => x.Email).EmailAddress();
RuleFor(x => x.Age).InclusiveBetween(18, 60);
}
}
} using System.Text.RegularExpressions;
using FluentValidation;
namespace FluentValidationSample.Models
{
public class RegisterModelValidator : AbstractValidator<RegisterModel>
{
public RegisterModelValidator()
{
RuleFor(x => x.Password)
.NotNull()
.WithMessage("Your password is required.")
.Length(6, 100)
.Must(password => hasValidPassword(password));
//...
}
private static bool hasValidPassword(string password)
{
var lowercase = new Regex("[a-z]+");
var uppercase = new Regex("[A-Z]+");
var digit = new Regex("(\\d)+");
var symbol = new Regex("(\\W)+");
return lowercase.IsMatch(password) &&
uppercase.IsMatch(password) &&
digit.IsMatch(password) &&
symbol.IsMatch(password);
}
}
} RuleFor(x => x.Password)
.NotNull()
.WithMessage("Your password is required.")
.Length(6, 100)
.Must(hasValidPassword); using System;
using FluentValidation;
using FluentValidation.Validators;
namespace FluentValidationSample.Models
{
public class EmailFromDomainValidator : PropertyValidator
{
private readonly string _domain;
public EmailFromDomainValidator(string domain)
: base("Email address {PropertyValue} is not from domain {domain}")
{
_domain = domain;
}
protected override bool IsValid(PropertyValidatorContext context)
{
if (context.PropertyValue == null) return false;
var split = context.PropertyValue.ToString().Split('@');
return split.Length == 2 && split[1].Equals(_domain, StringComparison.OrdinalIgnoreCase);
}
}
} RuleFor(x => x.Email)
.SetValidator(new EmailFromDomainValidator("gmail.com")); public static class CustomValidatorExtensions
{
public static IRuleBuilderOptions<T, string> EmailAddressFromDomain<T>(
this IRuleBuilder<T, string> ruleBuilder, string domain)
{
return ruleBuilder.SetValidator(new EmailFromDomainValidator(domain));
}
} RuleFor(x => x.Email).EmailAddressFromDomain("gmail.com"); public class RegisterModel
{
// ...
public Address Address { get; set; }
public ICollection<Phone> Phones { get; set; }
}
public class Phone
{
public string Number { get; set; }
public string Description { get; set; }
}
public class Address
{
public string Location { get; set; }
public string PostalCode { get; set; }
} public class PhoneValidator : AbstractValidator<Phone>
{
public PhoneValidator()
{
RuleFor(x => x.Number).NotNull();
}
}
public class AddressValidator : AbstractValidator<Address>
{
public AddressValidator()
{
RuleFor(x => x.PostalCode).NotNull();
RuleFor(x => x.Location).NotNull();
}
} public class RegisterModelValidator : AbstractValidator<RegisterModel>
{
public RegisterModelValidator()
{
// ...
RuleFor(x => x.Address).SetValidator(new AddressValidator());
RuleForEach(x => x.Phones).SetValidator(new PhoneValidator());
} namespace FluentValidationSample.ModelsValidations
{
public class ApiSettingsValidator : AbstractValidator<ApiSettings>
{
public ApiSettingsValidator()
{
this.CascadeMode = CascadeMode.StopOnFirstFailure; RuleFor(m => m.ServiceEndpoints)
.Must(s => s.GroupBy(s => s.Name).Count() == s.Count())
.OnFailure(_ => throw new ValidationException("names must be unique")); RuleFor(x => x.Surname)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull()
.NotEqual("foo"); RuleFor(x => x.Age)
.NotNull().WithMessage("سن نباید خالی باشد");
RuleFor(x => x.Experience)
.NotNull().WithMessage("تجربه کاری نباید خالی باشد")
.LowerThan(nameof(UserModel.Age)); <select asp-for="Age" class="form-control">
<option value="Null"></option>
<option value="1">1</option>
<option value="2">2</option>
<option value="2">3</option>
</select>
<select asp-for="Experience" class="form-control">
<option value="Null"></option>
<option value="1">1</option>
<option value="2">2</option>
<option value="2">3</option>
</select> RuleFor(x => x.StringField).NotNull().NotEmpty().WithMessage("...");