ایجاد ویژگیهای اعتبارسنجی سفارشی در ASP.NET Core 3.1 به همراه اعتبارسنجی سمت کلاینت آنها
نویسنده: زمانی فرهاد
تاریخ: ۱۳۹۹/۰۲/۲۶ ۱۹:۳۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public class LowerThanAttribute : ValidationAttribute
{
public LowerThanAttribute(string dependentPropertyName)
{
DependentPropertyName = dependentPropertyName;
}
public string DependentPropertyName { get; set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
int? currentPropertyValue = value as int?;
currentPropertyValue ??= 0;
var typeInfo = validationContext.ObjectInstance.GetType();
var dependentPropertyValue = Convert.ToInt32(typeInfo.GetProperty(DependentPropertyName)
.GetValue(validationContext.ObjectInstance, null));
var displayDependentProperyName = typeInfo.GetProperty(DependentPropertyName)
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.FirstOrDefault()?.Name;
if (!(currentPropertyValue.Value < dependentPropertyValue))
{
return new ValidationResult("مقدار {0} باید کمتر باشد از " + displayDependentProperyName);
}
return ValidationResult.Success;
}
} public class LowerThanAttribute : ValidationAttribute, IClientModelValidator
{
public LowerThanAttribute(string dependentPropertyName)
{
DependentPropertyName = dependentPropertyName;
}
public string DependentPropertyName { get; set; }
public void AddValidation(ClientModelValidationContext context)
{
var displayCurrentProperyName = context.ModelMetadata.ContainerMetadata
.ModelType.GetProperty(context.ModelMetadata.PropertyName)
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.FirstOrDefault()?.Name;
var displayDependentProperyName = context.ModelMetadata.ContainerMetadata
.ModelType.GetProperty(DependentPropertyName)
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.FirstOrDefault()?.Name;
MergeAttribute(context.Attributes, "data-val", "true");
MergeAttribute(context.Attributes, "data-val-lowerthan", $"{displayCurrentProperyName} باید کمتر باشد از {displayDependentProperyName}");
MergeAttribute(context.Attributes, "data-val-dependentpropertyname", "#" + DependentPropertyName);
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
int? currentPropertyValue = value as int?;
currentPropertyValue ??= 0;
var typeInfo = validationContext.ObjectInstance.GetType();
var dependentPropertyValue = Convert.ToInt32(typeInfo.GetProperty(DependentPropertyName)
.GetValue(validationContext.ObjectInstance, null));
var displayCurrentProperyName = typeInfo.GetProperty(DependentPropertyName)
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.FirstOrDefault()?.Name;
if (!(currentPropertyValue.Value < dependentPropertyValue))
{
return new ValidationResult("مقدار {0} باید کمتر باشد از " + displayCurrentProperyName);
}
return ValidationResult.Success;
}
} jQuery.validator.addMethod("lowerthan", function (value, element, param) {
var otherPropId = $(element).data('val-dependentpropertyname');
if (otherPropId) {
var otherProp = $(otherPropId);
if (otherProp) {
var otherVal = otherProp.val();
if (parseInt(otherVal) > parseInt(value)) {
return true;
}
return false;
}
}
return true;
});
jQuery.validator.unobtrusive.adapters.addBool("lowerthan"); <script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script> <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script> <script src="~/js/LowerThan.js"></script>
public class User
{
[Required]
[Display(Name ="نام کاربری")]
public string Username { get; set; }
[Required]
[Display(Name = "سن")]
public int Age { get; set; }
[LowerThan(nameof(Age))]
[Required]
[Display(Name = "سابقه کار")]
public int Experience { get; set; }
}
using FluentValidation;
public class CustomerValidator: AbstractValidator<Customer> {
public CustomerValidator() {
RuleFor(x => x.Surname).NotEmpty();
RuleFor(x => x.Forename).NotEmpty().WithMessage("Please specify a first name");
RuleFor(x => x.Discount).NotEqual(0).When(x => x.HasDiscount);
RuleFor(x => x.Address).Length(20, 250);
RuleFor(x => x.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
}
private bool BeAValidPostcode(string postcode) {
// custom postcode validating logic goes here
}
}
var customer = new Customer();
var validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);
bool success = results.IsValid;
IList<ValidationFailure> failures = results.Errors; public class NationalCodeClientValidator : ClientValidatorBase
{
#region Fields
private NationalCodeValidator NationalCodeValidator => (NationalCodeValidator)Validator;
#endregion Fields
#region Methods
#region Constructors
public NationalCodeClientValidator(PropertyRule rule, IPropertyValidator validator) : base(rule, validator)
{
}
#endregion Constructors
#region Override
public override void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
MergeAttribute(context.Attributes, "data-val-nationalcode", GetErrorMessage());
}
#endregion Override
#region Utility
private string GetErrorMessage()
{
var formatter = ValidatorOptions.MessageFormatterFactory().AppendPropertyName(Rule.GetDisplayName());
string messageTemplate;
try
{
messageTemplate = Validator.Options.ErrorMessageSource.GetString(null);
}
catch (FluentValidationMessageFormatException)
{
messageTemplate = ValidatorOptions.LanguageManager.GetStringForValidator<NotEmptyValidator>();
}
var message = formatter.BuildMessage(messageTemplate);
return message;
}
#endregion Utility
#endregion Methods
} public class NationalCodeValidator : PropertyValidator
{
#region Methods
#region Constructors
public NationalCodeValidator() : base(new LanguageStringSource(nameof(NationalCodeValidator)))
{
}
#endregion Constructors
#region Override
protected override bool IsValid(PropertyValidatorContext context)
{
return true;
}
#endregion Override
#endregion Methods
} .AddFluentValidation(option =>
{
option.RegisterValidatorsFromAssemblyContaining<CreateBankValidation>();
option.ConfigureClientsideValidation(AddFluentValidationClientModelValidatorProvider());
}) private static Action<FluentValidationClientModelValidatorProvider> AddFluentValidationClientModelValidatorProvider()
{
return clientSideValidation =>
{
clientSideValidation.Add(typeof(NationalCodeValidator), (context, rule, validator) => new NationalCodeClientValidator(rule, validator));
};
} // بررسی تایید کد ملی
function setCustomValidator() {
$.validator.unobtrusive.adapters.add('nationalcode', [], function (options) {
options.rules['nationalcode'] = {};
options.messages['nationalcode'] = options.message;
});
$.validator.addMethod('nationalcode', function (value, element, parameters) {
if (isValidIranianNationalCode(value)) return true;
return false;
});
}