asp mvc core 3 Проверка на стороне клиента для проверки пользовательских атрибутов - PullRequest
0 голосов
/ 18 октября 2019

Я создал собственный атрибут проверки, например, так:

public class UniqueTitleAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(
           object value, ValidationContext validationContext)
        {
            var context = (MyDBContext)validationContext.GetService(typeof(MyDBContext));
            var entity = context.Pages.SingleOrDefault(e => e.Title == value.ToString());

            if (entity != null)
            {
                return new ValidationResult(GetErrorMessage(value.ToString()));
            }
            return ValidationResult.Success;
        }

        public string GetErrorMessage(string title)
        {
            return $"Title {title} is already in use.";
        }
    }

И в модели:

[UniqueTitle]
public string Title { get; set; }

И он прекрасно работает, однако я бы тоже хотел бытьв состоянии добавить проверку на стороне клиента?

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

В пользовательском атрибуте проверки реализуйте интерфейс 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

0 голосов
/ 18 октября 2019
You have to use jquery and unobtrusive client side validation so fetch those urls in 
your page.

Use like 
<label asp-for="Name"></label>
<input asp-for="Name"/>
<span asp-validation-for="Name"></span>

Here i have taken example of Name as validation will fire on Name property but you can 
change property on which you want.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...