В пользовательском атрибуте проверки реализуйте интерфейс IClientModelValidator
и создайте метод AddValidation
. В методе AddValidation
добавьте data-
атрибуты для проверки следующим образом:
public class UniqueTitleAttribute : ValidationAttribute, IClientModelValidator
{
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
var context = (ApplicationDbContext)validationContext.GetService(typeof(ApplicationDbContext));
var entity = context.Articles.SingleOrDefault(e => e.Title == value.ToString());
if (entity != null)
{
return new ValidationResult(GetErrorMessage(value.ToString()));
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
Type obj = typeof(Article);
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
MergeAttribute(context.Attributes, "data-val", "true");
MergeAttribute(context.Attributes, "data-val-uniquetitle", GetErrorMessage());
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
public string GetErrorMessage()
{
return $"The title is already in use.";
}
public string GetErrorMessage(string title)
{
return $"Title {title} is already in use.";
}
}
Добавьте метод в библиотеку проверки jQuery. Он использует метод addMethod()
для указания нашей собственной функции проверки. Функция проверки получает значение, введенное в текстовое поле заголовка. Затем он выполняет проверку и возвращает логическое значение.
<div class="row">
<div class="col-md-4">
<form method="post" asp-action="CreateArticle">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="control-label"></label>
<input asp-for="Author" class="form-control" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
@section Scripts
{
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
var titlelist = @Html.Raw(Json.Serialize(ViewBag.TitleList));
$.validator.addMethod("uniquetitle",
function (value, element, param) {
if (titlelist.includes(value)) {
return false;
}
else {
return true;
}
});
$.validator.unobtrusive.adapters.addBool("uniquetitle");
</script>
}
Сохраните TitleList в ViewBag в методе Get представления, чтобы определить, используется ли заголовок из js:
public IActionResult CreateArticle()
{
ViewBag.TitleList = _context.Articles.Select(a => a.Title).ToList();
return View();
}
Результат: ![enter image description here](https://i.stack.imgur.com/m3UD3.gif)