Ненавязчивые правила не отображаются на стороне клиента - PullRequest
1 голос
/ 14 сентября 2011

У меня есть сценарий, на который действительно дан ответ здесь

Этот пример отлично работает.Я попытался использовать его в своем проекте, где я добавил точный серверный код для атрибута RequiredIf (копирование и вставка).Я также добавил jquery.validate.js, jquery.validate.unobtrusive.js и добавил скрипт, который добавляет метод 'requiredif' [$ .validator.addMethod ('requiredif', .......] и [$.validator.unobtrusive.adapters.add (........]

Все скопируйте и вставьте по ссылке выше. Через firebug я вижу все скрипты, загруженные в мое решение. Поля ввода все правильноидентифицировать requiredif ненавязчивый атрибут с помощью data-val-requiredif.

После нескольких часов отладки я заметил, что единственное различие между рабочим образцом и моим образцом состоит в том, что в рабочем образце, при просмотре через firebug, коллекция правилсодержит правила requiredif, а мой содержит все (длина строки и т. д.), за исключением requiredif, и объясняет, почему они не запускаются.

Атрибут RequiredIf был добавлен в модель представления, а код атрибута является прямымскопируйте по ссылке выше. Вызывается метод атрибута GetClientValidationRules, но правила не отображаются на стороне клиента.

Очень базар.Приветствуется любая помощь в отладке.

ОБНОВЛЕНИЕ

Вот атрибут RequiredIf:

public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
{
    private RequiredAttribute _innerAttribute = new RequiredAttribute();

    public string DependentProperty { get; set; }
    public object TargetValue { get; set; }

    public RequiredIfAttribute(string dependentProperty, object targetValue)
    {
        this.DependentProperty = dependentProperty;
        this.TargetValue = targetValue;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // get a reference to the property this validation depends upon
        var containerType = validationContext.ObjectInstance.GetType();
        var field = containerType.GetProperty(this.DependentProperty);

        if (field != null)
        {
            // get the value of the dependent property
            var dependentvalue = field.GetValue(validationContext.ObjectInstance, null);

            // compare the value against the target value
            if ((dependentvalue == null && this.TargetValue == null) ||
                (dependentvalue != null && dependentvalue.Equals(this.TargetValue)))
            {
                // match => means we should try validating this field
                if (!_innerAttribute.IsValid(value))
                    // validation failed - return an error
                    return new ValidationResult(this.ErrorMessage, new[] { validationContext.MemberName });
            }
        }

        return ValidationResult.Success;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule()
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "requiredif",
        };

        string depProp = BuildDependentPropertyId(metadata, context as ViewContext);

        // find the value on the control we depend on;
        // if it's a bool, format it javascript style 
        // (the default is True or False!)
        string targetValue = (this.TargetValue ?? "").ToString();
        if (this.TargetValue.GetType() == typeof(bool))
            targetValue = targetValue.ToLower();

        rule.ValidationParameters.Add("dependentproperty", depProp);
        rule.ValidationParameters.Add("targetvalue", targetValue);

        yield return rule;
    }

    private string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext)
    {
        // build the ID of the property
        string depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(this.DependentProperty);
        // unfortunately this will have the name of the current field appended to the beginning,
        // because the TemplateInfo's context has had this fieldname appended to it. Instead, we
        // want to get the context as though it was one level higher (i.e. outside the current property,
        // which is the containing object (our Person), and hence the same level as the dependent property.
        var thisField = metadata.PropertyName + "_";
        if (depProp.StartsWith(thisField))
            // strip it off again
            depProp = depProp.Substring(thisField.Length);
        return depProp;
    }
}

GetClientValidationRules действительно получает удар.Пример атрибута, добавленного в модель представления:

[RequiredIf("Openid_Identifier", "", ErrorMessage = "Please choose a proper login.")]
[StringLength(50, ErrorMessage = "Email address is too long.")]        
[RegularExpression(@"^[\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?$", ErrorMessage = "Incorrect email format.")]
public string Email { get; set; } 

StringLength и RegEx оба работают, и я вижу ошибку проверки.Обязательно, если явно нет.В примере, который работает по исходной ссылке, если я поставлю точку останова внутри

$.validator.addMethod('requiredif',
function (value, element, parameters) {
    debugger;
    var id = '#' + parameters['dependentproperty'];

, она попадет.В моем решении оно никогда не попадет из-за того, что я упомянул выше (обязательно, если не было добавлено в коллекцию правил).

ОБНОВЛЕНИЕ 2

Я используюпараллельный загрузчик javascript (headjs) для параллельной загрузки файлов javascript.И если у меня есть:

<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/headjs/0.96/head.min.js"></script>
<script type="text/javascript">
head.js("http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.min.js")
    .js("http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js")
    .js("http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min.js")
    .js("@Url.ScriptFromLocal("requiredif.js")");
</script>

Тогда это не сработает.Если у меня есть обычные теги скрипта, тогда все хорошо.Я использую параллельный загрузчик везде, и он отлично работает, включая готовые атрибуты.Пользовательские файлы не нужны, если я параллельно загружаю файлы js.

1 Ответ

1 голос
/ 15 сентября 2011

Что-нибудь динамическое, будь то динамический html или динамический javascript-файл, необходимо проанализировать данные с помощью $ .validator.unobtrusive.parse ('# some_form_container'), и все в порядке.

Спасибо тем, кто откликнулся.

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