Asp.net mvc 3 不引人注目的规则不会呈现给客户端

Asp.net mvc 3 不引人注目的规则不会呈现给客户端,asp.net-mvc-3,Asp.net Mvc 3,我有一个场景,它实际上已经被回答了 那个样品很好用。我试着在我的项目中使用它,为RequiredIf属性(复制和粘贴)添加了确切的服务器端代码。我还添加了jquery.validate.js、jquery.validate.unobtrusive.js,并添加了一个脚本,该脚本添加了'requiredif'方法[$.validator.addMethod('requiredif',…..)和[$.validator.unobtrusive.adapters.add(……] 从上面的链接复制和粘贴

我有一个场景,它实际上已经被回答了

那个样品很好用。我试着在我的项目中使用它,为RequiredIf属性(复制和粘贴)添加了确切的服务器端代码。我还添加了jquery.validate.js、jquery.validate.unobtrusive.js,并添加了一个脚本,该脚本添加了'requiredif'方法[$.validator.addMethod('requiredif',…..)和[$.validator.unobtrusive.adapters.add(……]

从上面的链接复制和粘贴所有内容。通过firebug,我可以看到在我的解决方案中加载的所有脚本。输入字段都通过数据val requiredif正确标识requiredif untrusive属性

经过数小时的调试,我注意到工作示例和我的示例之间的唯一区别是,在工作示例中,通过firebug查看时,规则集合确实包含requiredif规则,而我的包含除requiredif之外的所有规则(stringlength等),并解释了它们不触发的原因

属性RequiredIf已添加到viewmodel,该属性的代码是上面链接的直接副本。正在调用该属性的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;
    }
}
StringLength和RegEx都能工作,我看到了验证错误。RequiredIf显然不能。在从原始链接开始工作的示例中,如果我将断点放在

$.validator.addMethod('requiredif',
function (value, element, parameters) {
    debugger;
    var id = '#' + parameters['dependentproperty'];
在我的解决方案中,由于我上面提到的原因,它从未被击中(requiredif没有被添加到规则集合)

更新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>

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”));

如果我有正则脚本标记,那么一切都很好。我在任何地方都使用并行加载程序,它可以很好地工作,包括开箱即用的属性。如果我并行加载js文件,自定义属性是不行的。

任何动态的东西,无论是动态html还是动态javascript文件,都需要使用$.validator.unobtrusive.parse(“#某些#form_容器”),一切正常


感谢您的回复。

任何动态内容,无论是动态html还是动态javascript文件,都需要使用$.validator.unobtrusive.parse(“#某个表单_容器”)重新分析数据,一切正常


感谢您的回复。

您说您是从链接文章中的代码中复制和粘贴的。文章中的
RequiredIfAttribute
类是空的。实际的RequiredIfAttribute代码在文章底部链接的.zip文件中。您是对的。我确实下载了zip并添加了实际的代码。只是忘记了提到这一点。我只是想澄清一下。您仍然遇到同样的问题?是的。规则集合没有所需的IF。其他一切似乎都很好。您是否在
GetClientValidationRules
方法的末尾设置了断点,只是为了确认从该方法返回了规则?您说您是从链接文章中的代码。文章中的
RequiredIfAttribute
类是空的。实际的RequiredIfAttribute代码在文章底部链接的.zip文件中。你是对的。我确实下载了zip并添加了实际的代码。只是忘了提及。只是为了澄清一下。你仍然遇到同样的问题吗?是的。规则集合没有requiredif。其他一切似乎都很好。您是否在
GetClientValidationRules
方法的末尾设置了断点,只是为了确认从该方法返回了规则?对于本文作者上面提到的示例,解析调用应该发生在哪里?对于示例menti这篇文章的作者在上面提到,解析调用应该发生在哪里?
<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>