Проверка пользовательской модели в форме ASP.Net core v3.1 MVC ajax, похоже, не работает

Я работаю над проектом ASP.Net core 3.1 MVC, в котором мне нужно создать собственный валидатор, и я хочу, чтобы он работал как на стороне клиента, так и на стороне сервера (например, обязательный атрибут).

Я разработал простой пользовательский валидатор, как показано ниже, только для POC -

public class ImportantAttribute : ValidationAttribute, IClientModelValidator
    {
        public void AddValidation(ClientModelValidationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            AttributeUtils.MergeAttribute(context.Attributes, "data-val", "true");
            AttributeUtils.MergeAttribute(context.Attributes, "data-val-important", FormatErrorMessage(context.ModelMetadata.GetDisplayName()));
        }

        public class AttributeUtils
        {
            public static 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)
        {
            if (value != null)
            {
                string val = value.ToString();
                if (val.Contains("hello"))
                {
                    return ValidationResult.Success;
                }
            }
            return new ValidationResult("Value not valid");
        }
    }

и использовал этот атрибут для свойства и создал представление, используя ту же модель.

Они изменили тег формы, чтобы он стал формой ajax, например:

<form asp-action="Index" role="form" data-ajax="true" data-ajax-method="post">
            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" value="SGSM" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
 </form>

Затем я добавил ниже java-скрипт -

$(document).ready(() => {
    console.log('I\'m ready bro');

    $.validator.addMethod("important",
        function (value, element, params) {
            console.log('1', value);
            return value.contains('hello');
        }, "Not OK");

    $.validator.unobtrusive.adapters.add("important",
        ['important'],
        function (options) {
            console.log('2', options);
            options.rules["important"] = options.important;
            options.messages["important"] = options.message;
        });
});

Когда я запускаю это, вводя любое значение в текстовое поле и отправляя форму, на странице не отображается никакого сообщения об ошибке, но если я поставлю точку останова в методе действия, ModelState покажет правильную информацию.

Если я создам форму как обычную форму (т. е. форму без ajax), все будет работать так, как ожидалось.

Я много искал, но не мог найти ничего связанного.


person Awesh Vishwakarma    schedule 09.10.2020    source источник


Ответы (1)


Основываясь на вашем коде и требованиях, я внес некоторые изменения в специальный код проверки на стороне клиента, который хорошо работает для меня, вы можете передать его.

<div class="row">
    <div class="col-md-4">
        <form asp-action="Index" method="post" role="form" data-ajax="true" data-ajax-method="post" data-ajax-complete="completed">
            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" 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 src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.js"></script>
    <script>
        $(document).ready(() => {
            console.log('I\'m ready bro');
        });

        completed = () => {
            alert('Request completed!');
        };

        $.validator.addMethod("important",
            function (value, element, params) {
                console.log('1', value);
                return value.includes('hello');
            }, "Not OK");

        $.validator.unobtrusive.adapters.add("important",
            ['important'],
            function (options) {
                console.log('2', options);

                var element = $(options.form).find('input#Name')[0];

                options.rules["important"] = [element, ''];
                options.messages["important"] = options.message;
            });

    </script>
}

Результат испытаний

введите здесь описание изображения

person Fei Han    schedule 09.10.2020
comment
Мы можем сделать одно исправление здесь, в этой строке -> var element = $(options.form).find('input#Name')[0]; замените его на var element = options.element; - person Awesh Vishwakarma; 12.10.2020
comment
У меня есть сомнения здесь в реализации $.validator.addMethod, требуется ли также писать логику проверки (value.includes('hello');) в своей функции обратного вызова, потому что она уже написана в пользовательском атрибуте проверки? - person Awesh Vishwakarma; 13.10.2020