我有一个实际回答的情景here
该样本完美无缺。我尝试在我的项目中使用它,我在其中添加了RequiredIf属性的精确服务器端代码(复制和粘贴)。我还添加了jquery.validate.js,jquery.validate.unobtrusive.js并添加了一个添加'requiredif'方法的脚本[$ .validator.addMethod('requiredif',.......]和[$ .validator.unobtrusive.adapters.add(........]
从上面的链接中复制并粘贴。通过firebug,我看到我的解决方案中加载了所有脚本。输入字段都通过data-val-requiredif正确识别requiredif unobtrusive属性。
经过几个小时的调试后,我注意到工作样本和我的样本之间的唯一区别是,在工作样本中,当通过firebug查看时,规则集合确实包含requiredif规则,而我的包含所有(stringlength等)除外对于requiredif并解释他们为什么不开火。
属性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;
}
}
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'];
确实受到了打击。在我的解决方案中,由于我上面提到的内容,它永远不会被击中(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>
然后它不起作用。如果我有常规的脚本标签,那么一切都很好。我在任何地方都使用并行加载程序,它工作正常,包括可行的开箱即用属性。如果我并行加载js文件,自定义的是不行。
答案 0 :(得分:1)
任何动态,无论是动态html还是动态javascript文件,都需要使用$ .validator.unobtrusive.parse('#some_form_container')重新分析数据,一切都很好。
感谢那些回复的人。