Пользовательский атрибут проверки mvc3 не проверяется на стороне клиента - PullRequest
4 голосов
/ 15 февраля 2012

Создан пользовательский атрибут проверки, и я бы хотел, чтобы он работал и на стороне клиента. Вот модель класса

public class CreditCardAttribute : ValidationAttribute, IClientValidatable
    {
        public override bool IsValid(object value)
        {
            var number = Convert.ToString(value);
            return IsValidNumber(number);
        }
        private bool IsValidNumber(string number)
        {
            int[] DELTAS = new int[] { 0, 1, 2, 3, 4, -4, -3, -2, -1, 0 };
            int checksum = 0;
            char[] chars = number.ToCharArray();
            for (int i = chars.Length - 1; i > -1; i--)
            {
                int j = ((int)chars[i]) - 48;
                checksum += j;
                if (((i - chars.Length) % 2) == 0)
                    checksum += DELTAS[j];
            }

            return ((checksum % 10) == 0);
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            yield return new ModelClientValidationRule { 
            ErrorMessage = this.ErrorMessage,
            ValidationType = "CreditCard"
            };

        }
    }

JQuery:

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


    jQuery.validator.unobtrusive.adapters.add('CreditCard', { }, function(options){
        options.rules['CreditCardtest'] = true;
        options.messages['CreditCardtest'] = options.message;
    });

Я не уверен, что должно идти в CreditCardTest, я хочу переписать сюда то, что у меня есть в модели?

Спасибо

Ответы [ 2 ]

4 голосов
/ 15 февраля 2012

Проверка номера кредитной карты - это, вероятно, то, для чего вы не хотите осуществлять проверку клиента.

Но если вам интересно, как этого добиться в общем случае, вам придется реализовать ту же логику, что и на вашем сервере, в javascript.

Есть только одна вещь, которая не так сваш пользовательский атрибут проверки, и это имя типа проверки, который должен содержать только строчные буквы:

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    yield return new ModelClientValidationRule 
    { 
        ErrorMessage = this.ErrorMessage,
        ValidationType = "creditcard" // this should be only lowercase letters
    };
}

Как только мы исправим, мы можем реализовать ту же логику проверки на клиенте:

@model MyViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    var isValidNumber = function (value, element, params) {
        var DELTAS = [0, 1, 2, 3, 4, -4, -3, -2, -1, 0];
        var checksum = 0;
        for (var i = value.length - 1; i > -1; i--) {
            var j = value.charCodeAt(i) - 48;

            checksum += j;
            if (((i - value.Length) % 2) == 0) {
                checksum += DELTAS[j];
            }
        }
        return (checksum % 10) == 0;
    };

    jQuery.validator.addMethod('CreditCardtest', isValidNumber);

    jQuery.validator.unobtrusive.adapters.add('creditcard', { }, function (options) {
        options.rules['CreditCardtest'] = true;
        options.messages['CreditCardtest'] = options.message;
    });
</script>

@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.Number)
    @Html.ValidationMessageFor(x => x.Number)
    <button type="submit">OK</button>
}

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

1 голос
/ 15 февраля 2012

Да, если вы хотите проверить клиентскую часть, вам нужно написать JavaScript-версию вашего кода проверки на стороне сервера. (Потому что это заданный вопрос, и пришло время идти домой.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...