استفاده از Fluent Validation در برنامههای ASP.NET Core - قسمت سوم - اعتبارسنجی سمت کلاینت
نویسنده: وحید نصیری
تاریخ: ۱۳۹۹/۰۴/۰۱ ۱۱:۴۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
using System;
using FluentValidation;
using FluentValidation.Validators;
namespace FluentValidationSample.Models
{
public class LowerThanValidator : PropertyValidator
{
public string DependentProperty { get; set; }
public LowerThanValidator(string dependentProperty) : base($"باید کمتر از {dependentProperty} باشد")
{
DependentProperty = dependentProperty;
}
protected override bool IsValid(PropertyValidatorContext context)
{
if (context.PropertyValue == null)
{
return false;
}
var typeInfo = context.Instance.GetType();
var dependentPropertyValue =
Convert.ToInt32(typeInfo.GetProperty(DependentProperty).GetValue(context.Instance, null));
return int.Parse(context.PropertyValue.ToString()) < dependentPropertyValue;
}
}
public static class CustomFluentValidationExtensions
{
public static IRuleBuilderOptions<T, int> LowerThan<T>(
this IRuleBuilder<T, int> ruleBuilder, string dependentProperty)
{
return ruleBuilder.SetValidator(new LowerThanValidator(dependentProperty));
}
}
} using FluentValidation;
using FluentValidation.AspNetCore;
using FluentValidation.Internal;
using FluentValidation.Resources;
using FluentValidation.Validators;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
namespace FluentValidationSample.Models
{
public class LowerThanClientValidator : ClientValidatorBase
{
private LowerThanValidator LowerThanValidator
{
get { return (LowerThanValidator)Validator; }
}
public LowerThanClientValidator(PropertyRule rule, IPropertyValidator validator) :
base(rule, validator)
{
}
public override void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
MergeAttribute(context.Attributes, "data-val-LowerThan", GetErrorMessage(context));
MergeAttribute(context.Attributes, "data-val-LowerThan-dependentproperty", LowerThanValidator.DependentProperty);
}
private string GetErrorMessage(ClientModelValidationContext context)
{
var formatter = ValidatorOptions.MessageFormatterFactory().AppendPropertyName(Rule.GetDisplayName());
string messageTemplate;
try
{
messageTemplate = Validator.Options.ErrorMessageSource.GetString(null);
}
catch (FluentValidationMessageFormatException)
{
messageTemplate = ValidatorOptions.LanguageManager.GetStringForValidator<NotEmptyValidator>();
}
return formatter.BuildMessage(messageTemplate);
}
}
} <input dir="rtl" type="number" data-val="true" data-val-lowerthan="باید کمتر از Age باشد" data-val-lowerthan-dependentproperty="Age" data-val-required="'سابقه کار' must not be empty." id="Experience" name="Experience" value="">
public class UserModel
{
[Display(Name = "نام کاربری")]
public string Username { get; set; }
[Display(Name = "سن")]
public int Age { get; set; }
[Display(Name = "سابقه کار")]
public int Experience { get; set; }
}
public class UserValidator : AbstractValidator<UserModel>
{
public UserValidator()
{
RuleFor(x => x.Username).NotNull();
RuleFor(x => x.Age).NotNull();
RuleFor(x => x.Experience).LowerThan(nameof(UserModel.Age)).NotNull();
}
} namespace FluentValidationSample.Web
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddFluentValidation(
fv =>
{
fv.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly());
fv.RegisterValidatorsFromAssemblyContaining<RegisterModelValidator>();
fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
fv.ConfigureClientsideValidation(clientSideValidation =>
{
clientSideValidation.Add(
validatorType: typeof(LowerThanValidator),
factory: (context, rule, validator) => new LowerThanClientValidator(rule, validator));
});
}
);
} <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script> <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script> <script src="~/js/site.js" asp-append-version="true"></script>
$.validator.unobtrusive.adapters.add('LowerThan', ['dependentproperty'], function (options) {
options.rules['LowerThan'] = {
dependentproperty: options.params['dependentproperty']
};
options.messages['LowerThan'] = options.message;
});
$.validator.addMethod('LowerThan', function (value, element, parameters) {
var dependentProperty = '#' + parameters['dependentproperty'];
var dependentControl = $(dependentProperty);
if (dependentControl) {
var targetvalue = dependentControl.val();
if (parseInt(targetvalue) > parseInt(value)) {
return true;
}
return false;
}
return true;
}); @using FluentValidationSample.Models
@model UserModel
@{
ViewData["Title"] = "Home Page";
}
<div dir="rtl">
<form asp-controller="Home"
asp-action="RegisterUser"
method="post">
<fieldset class="form-group">
<legend>ثبت نام</legend>
<div class="form-group row">
<label asp-for="Username" class="col-md-2 col-form-label text-md-left"></label>
<div class="col-md-10">
<input dir="rtl" asp-for="Username" class="form-control" />
<span asp-validation-for="Username" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="Age" class="col-md-2 col-form-label text-md-left"></label>
<div class="col-md-10">
<input dir="rtl" asp-for="Age" class="form-control" />
<span asp-validation-for="Age" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label asp-for="Experience" class="col-md-2 col-form-label text-md-left"></label>
<div class="col-md-10">
<input dir="rtl" asp-for="Experience" class="form-control" />
<span asp-validation-for="Experience" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<label class="col-md-2 col-form-label text-md-left"></label>
<div class="col-md-10 text-md-right">
<button type="submit" class="btn btn-info col-md-2">ارسال</button>
</div>
</div>
</fieldset>
</form>
</div>
private string GetErrorMessage(ClientModelValidationContext context)
{
var configuration = ValidatorOptions.Global;
var formatter = configuration.MessageFormatterFactory().AppendPropertyName(Rule.GetDisplayName());
string messageTemplate;
try
{
messageTemplate = Validator.Options.ErrorMessageSource.GetString(null);
}
catch (FluentValidationMessageFormatException)
{
messageTemplate = configuration.LanguageManager.GetStringForValidator<NotEmptyValidator>();
}
return formatter.BuildMessage(messageTemplate);
}