Подтвердить что ты не робот

Проверка на стороне клиента в атрибуте пользовательской проверки - asp.net mvc 4

Я следил за некоторыми статьями и учебными пособиями через Интернет, чтобы создать собственный атрибут проверки, который также поддерживает проверку на стороне клиента на веб-сайте asp.net mvc 4. Это то, что у меня есть до сих пор:

RequiredIfAttribute.cs

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] //Added
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
{
    private readonly string condition;
    private string propertyName; //Added

    public RequiredIfAttribute(string condition)
    {
        this.condition = condition;
        this.propertyName = propertyName; //Added
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        PropertyInfo propertyInfo = validationContext.ObjectType.GetProperty(this.propertyName); //Added
        Delegate conditionFunction = CreateExpression(validationContext.ObjectType, _condition);
        bool conditionMet = (bool)conditionFunction.DynamicInvoke(validationContext.ObjectInstance);

        if (conditionMet)
        {
            if (value == null)
            {
                return new ValidationResult(FormatErrorMessage(null));
            }
        }

        return ValidationResult.Success;
    }

    private Delegate CreateExpression(Type objectType, string expression)
    {
        LambdaExpression lambdaExpression = System.Linq.Dynamic.DynamicExpression.ParseLambda(objectType, typeof(bool), expression); //Added
        Delegate function = lambdaExpression.Compile();
        return function;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var modelClientValidationRule = new ModelClientValidationRule
        {
            ValidationType = "requiredif",
            ErrorMessage = ErrorMessage //Added
        };

        modelClientValidationRule.ValidationParameters.Add("param", this.propertyName); //Added
        return new List<ModelClientValidationRule> { modelClientValidationRule };
    }
}

Затем я применил этот атрибут в свойстве класса, подобного этому

[RequiredIf("InAppPurchase == true", "InAppPurchase", ErrorMessage = "Please enter an in app purchase promotional price")] //Added "InAppPurchase"
public string InAppPurchasePromotionalPrice { get; set; }

public bool InAppPurchase { get; set; }

Итак, что я хочу сделать, это отобразить сообщение об ошибке, в котором поле InAppPurchasePromotionalPrice требуется, когда поле InAppPurchase истинно (это означает, что оно отмечено в форме). Ниже приведен соответствующий код формы:

<div class="control-group">
                <label class="control-label" for="InAppPurchase">Does your app include In App Purchase?</label>
                <div class="controls">
                    @Html.CheckBoxFor(o => o.InAppPurchase)
                    @Html.LabelFor(o => o.InAppPurchase, "Yes")
                </div>
            </div>
            <div class="control-group" id="InAppPurchasePromotionalPriceDiv" @(Model.InAppPurchase == true ? Html.Raw("style='display: block;'") : Html.Raw("style='display: none;'"))>
                <label class="control-label" for="InAppPurchasePromotionalPrice">App Friday Promotional Price for In App Purchase: </label>
                <div class="controls">
                    @Html.TextBoxFor(o => o.InAppPurchasePromotionalPrice, new { title = "This should be at the lowest price tier of free or $.99, just for your App Friday date." })
                    <span class="help-inline">
                        @Html.ValidationMessageFor(o => o.InAppPurchasePromotionalPrice)
                    </span>
                </div>
            </div>

Этот код работает отлично, но когда я отправляю форму, для отправки сообщения на сервер запрашивается полный пост. Поэтому я создал код JavaScript, чтобы включить проверку на стороне клиента:

requiredif.js

(function ($) {
    $.validator.addMethod('requiredif', function (value, element, params) {
        /*var inAppPurchase = $('#InAppPurchase').is(':checked');

        if (inAppPurchase) {
            return true;
        }

        return false;*/

        var isChecked = $(param).is(':checked');

        if (isChecked) {
            return false;
        }

        return true;
    }, '');

    $.validator.unobtrusive.adapters.add('requiredif', ['param'], function (options) {
        options.rules["requiredif"] = '#' + options.params.param;
        options.messages['requiredif'] = options.message;
    });
})(jQuery);

Это предложенный способ в msdn и учебниках, которые я нашел

Конечно, я также ввел необходимые скрипты в форму:

  • jquery.unobtrusive-ajax.min.js
  • jquery.validate.min.js
  • jquery.validate.unobtrusive.min.js
  • requiredif.js

НО... проверка на стороне клиента все еще не работает. Не могли бы вы помочь мне найти то, что мне не хватает? Спасибо заранее.

4b9b3361

Ответ 1

Взгляните на это: http://thewayofcode.wordpress.com/tag/custom-unobtrusive-validation/

Используя этот учебник, я получил свой код проверки подлинности без проблем. Единственное отличие, которое я могу заметить в вашем коде, - это то, как вы создали функцию $.validator.unobtrusive.adapters.add. Параметры немного разные, но, может быть, проблема в том, что вы не определили часть rule вашего адаптера.

Попробуйте использовать что-то вроде этого:

$.validator.unobtrusive.adapters.add("requiredif", ["requiredif"], function (options) {
    options.rules["requiredif"] = "#" + options.params.requiredif;
    options.messages["requiredif"] = options.message;
});

или

$.validator.unobtrusive.adapters.add("requiredif", function (options) {
    options.rules["requiredif"] = "#" + options.element.name.replace('.', '_'); // mvc html helpers
    options.messages["requiredif"] = options.message;
});

О rule (взято из ссылки):

Массив правил jQuery для этого элемента HTML. Ожидается адаптер для добавления элементов (ов) в этот массив правил для конкретного jQuery Validate валидаторы, которые он хочет присоединить. Имя - это имя jQuery Validate, а значение - значения параметров для jQuery Правило проверки.

Ответ 2

Стоит отметить, что атрибут [RequiredIf] должен быть добавлен во второе поле формы в модели представления, чтобы проверка клиента работала.