Пользовательская проверка на стороне клиента не запускается в ASP.NET Core - PullRequest
0 голосов
/ 20 сентября 2019

Я добавляю в свой код настраиваемый атрибут проверки, и он отлично работает на стороне сервера.Однако на стороне клиента метод и адаптер зарегистрированы, но функция проверки никогда не вызывается.

Я работаю в .NET Core 2.2 с использованием MVC.Я удалил оболочку $ (Document) .Ready, как предложено в другом месте, и проверил, что все регистры совпадают.

Ниже приводится MRE

Атрибут проверки теста:

public class TestValidationAttribute : ValidationAttribute, IClientModelValidator
{
    public TestValidationAttribute(string name)
    {
        _name = name;
    }

    private string _name;

    protected override ValidationResult IsValid(Object value, ValidationContext validationContext)
    {
        return new ValidationResult($"{_name} has been validated");
    }

    void IClientModelValidator.AddValidation(ClientModelValidationContext context)
    {
        context.Attributes.Add("data-val", "true");
        context.Attributes.Add("data-val-testvalidation", $"{_name} has been validated client side");
        context.Attributes.Add("data-val-testvalidation-name", _name);
    }
}

Модель:

public class TestModel
{
    [TestValidation("Hello World!")]
    [Display(Name = "Test Value")]
    public string TestValue { get; set; }
}

Вид:

<div class="form-group">
    @using (Html.BeginForm())
    {
    <div class="row">
        @Html.LabelFor(m => m.TestValue)
    </div>
    <div class="row">
        @Html.EditorFor(m => m.TestValue)
    </div>
    <div class="row">
        @Html.ValidationMessageFor(m => m.TestValue)
    </div>
    <div class="row">
        <input type="submit" value="Submit" />
    </div>
    }
</div>

Валидация JS:

$(function ($) {
    $.validator.addMethod('testvalidation',
        function (value, element, params) {
            return false;
        });

    $.validator.unobtrusive.adapters.add('testvalidation', ['name'],
        function (options) {
            options.rules['testvalidation'] = { name: options.params['name'] };
            options.messages['testvalidation'] = options.messages;
        });
}(jQuery));

Сгенерированный HTML:

<div class="form-group">
<form action="/" method="post">    <div class="row">
        <label for="TestValue">Test Value</label>
    </div>
    <div class="row">
        <input class="text-box single-line" data-val="true" data-val-testvalidation="Hello World! has been validated client side" data-val-testvalidation-name="Hello World!" id="TestValue" name="TestValue" type="text" value="" />
    </div>
    <div class="row">
        <span class="field-validation-valid" data-valmsg-for="TestValue" data-valmsg-replace="true"></span>
    </div>
    <div class="row">
        <input type="submit" value="Submit" />
    </div>
<input name="__RequestVerificationToken" type="hidden" value="" /></form></div>

        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2019 - WebApplication1 - <a href="/Home/Privacy">Privacy</a>
        </div>
    </footer>


        <script src="/lib/jquery/dist/jquery.js"></script>
        <script src="/lib/bootstrap/dist/js/bootstrap.bundle.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/testvalidation.js"></script>
    <script src="/js/site.js?v=4q1jwFhaPaZgr8WAUSrux6hAuh0XDg9kPS3xIVq36I0"></script>

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Вам нужно изменить options.params['name'] на options.params.name.Вот простой способ, как показано ниже:

 <script>
        $.validator.addMethod('testvalidation',
            function (value, element, params) {
                if (value == "") {
                    return false;
                }
                return true;                               
            },"Please set a value");
        $.validator.unobtrusive.adapters.add('testvalidation', ['name'],
            function (options) {
                console.log(options);
                options.rules['testvalidation'] = { name: options.params.name};
                console.log(options.rules['testvalidation']);
                options.messages['testvalidation'] = options.message.messages;
            });
</script>

Результат: enter image description here

0 голосов
/ 20 сентября 2019

Я создал рабочий пример на основе вашего вопроса и кода.

public class TestModel
{
    [TestValidation("Hello world!", ErrorMessage = "You did not write Hello world!.")]
    [Display(Name = "Test Value")]
    public string TestValue { get; set; }
}
    [AttributeUsage(AttributeTargets.Property)]
    public class TestValidationAttribute : ValidationAttribute, IClientModelValidator
    {
        private object _expectedValue;
        public TestValidationAttribute(object expectedValue)
        {
            _expectedValue = expectedValue;
        }

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            return Equals(value, _expectedValue);
        }

        public void AddValidation(ClientModelValidationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            context.Attributes.Add("data-val", "true");
            context.Attributes.Add("data-val-testvalidation", ErrorMessage);
            context.Attributes.Add("data-val-testvalidation-expectedvalue", _expectedValue.ToString());
        }
    }

Обратите внимание, что проверка jQuery регистрирует свои правила перед загрузкой DOM.Если вы попытаетесь зарегистрировать свой адаптер после загрузки DOM, ваши правила не будут обработаны.Так что оберните его в самовыполняющуюся функцию.

$(function ($) {
    $.validator.addMethod('testvalidation', function (value, element, params) {
        var expectedValue = params.expectedvalue;
        if (!expectedValue) return false;
        var actual = element.value;
        if (actual === expectedValue) return true;
        return false;
    });

    $.validator.unobtrusive.adapters.add('testvalidation', ['expectedvalue'],
        function (options) {

            // Add validation rule for HTML elements that contain data-testvalidation attribute

            options.rules['testvalidation'] = {

                // pass the data from data-testvalidation-expectedvalue to
                // the params argument of the testvalidation method

                expectedvalue: options.params['expectedvalue']
        };
        // get the error message from data-testvalidation-expectedvalue
        // so that unobtrusive validation can use it when validation rule fails
        options.messages['testvalidation'] = options.message;
    });
}(jQuery));

Правильный способ загрузки скриптов будет


@section Scripts{
    @Html.Partial("_ValidationScriptsPartial"); // Or instead like this:
    <!--<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>-->
    <!--<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js">-->
    <script src="~/js/testvalidation.js"></script>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...