Asp.net mvc MVC 3.0中的运行时条件验证(必填字段)
我的模型类中几乎没有地址行字段,这会根据所选国家/语言更改其行为(必需/非必需) 例如,英国应该有3个地址行作为必填输入字段,而在美国,它应该只有2个必填字段 我曾尝试使用自定义验证器“RequiredIf”&根据另一个可为null的布尔属性打开或关闭它;但它不起作用 我的模型的相关属性包括:Asp.net mvc MVC 3.0中的运行时条件验证(必填字段),asp.net-mvc,asp.net-mvc-3,validation,Asp.net Mvc,Asp.net Mvc 3,Validation,我的模型类中几乎没有地址行字段,这会根据所选国家/语言更改其行为(必需/非必需) 例如,英国应该有3个地址行作为必填输入字段,而在美国,它应该只有2个必填字段 我曾尝试使用自定义验证器“RequiredIf”&根据另一个可为null的布尔属性打开或关闭它;但它不起作用 我的模型的相关属性包括: public bool? IsAddressLine3Mandatory { get; set; } [RequiredIf("IsAddressline3Mandatory", true, Error
public bool? IsAddressLine3Mandatory { get; set; }
[RequiredIf("IsAddressline3Mandatory", true, ErrorMessage = "Address line 3 is mandatory for UK")]
public string AddressLine3 { get; set; }
我正在从数据库中获取国家信息,并在HTTPGet操作方法中为该视图设置IsAddressline3Mandatory字段
我试图实现客户端和服务器端的验证
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;
}
}
公共类requireditAttribute:ValidationAttribute,IClientValidable
{
私有RequiredAttribute_innerAttribute=新RequiredAttribute();
公共字符串依赖属性{get;set;}
公共对象TargetValue{get;set;}
public requirediftAttribute(字符串相关属性,对象targetValue)
{
this.DependentProperty=DependentProperty;
this.TargetValue=TargetValue;
}
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
//获取对此验证所依赖的属性的引用
var containerType=validationContext.ObjectInstance.GetType();
var field=containerType.GetProperty(this.DependentProperty);
如果(字段!=null)
{
//获取依赖属性的值
var dependentvalue=field.GetValue(validationContext.ObjectInstance,null);
//将该值与目标值进行比较
if((dependentvalue==null&&this.TargetValue==null)||
(dependentvalue!=null&&dependentvalue.Equals(this.TargetValue)))
{
//match=>表示我们应该尝试验证此字段
如果(!\u innerAttribute.IsValid(值))
//验证失败-返回错误
返回新的ValidationResult(this.ErrorMessage,new[]{validationContext.MemberName});
}
}
返回ValidationResult.Success;
}
公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文)
{
var rule=new ModelClientValidationRule()
{
ErrorMessage=FormatErrorMessage(metadata.GetDisplayName()),
ValidationType=“requiredif”,
};
string depProp=BuildDependentPropertyId(元数据,上下文为ViewContext);
//找到我们所依赖的控件的值;
//如果是bool,则将其格式化为javascript样式
//(默认值为True或False!)
字符串targetValue=(this.targetValue???).ToString();
if(this.TargetValue.GetType()==typeof(bool))
targetValue=targetValue.ToLower();
rule.ValidationParameters.Add(“dependentproperty”,depProp);
规则.ValidationParameters.Add(“targetvalue”,targetvalue);
收益率-收益率规则;
}
私有字符串BuildDependentPropertyId(ModelMetadata元数据,ViewContext)
{
//生成属性的ID
string depProp=viewContext.ViewData.TemplateInfo.GetFullHtmlFieldDid(this.DependentProperty);
//不幸的是,这将在开头追加当前字段的名称,
//因为TemplateInfo的上下文已经附加了这个字段名
//想要获得更高一级的上下文(即在当前属性之外,
//它是包含对象(我们的人),因此与从属属性处于同一级别。
var thisField=metadata.PropertyName+“\uux”;
if(depProp.StartsWith(此字段))
//再把它剥掉
depProp=depProp.Substring(thisField.Length);
返回depProp;
}
}
您可以展示您的模型吗?另外,您如何根据国家/地区选择来切换IsAddressline3Mandatory
属性的值?@DarinDimitrov:我已经添加了相关的模型属性。我正在从我们的数据库中获取国家/地区信息,并在HTTPGet操作方法中为在视图中。但是用户可以在视图中更改国家,对吗?在这种情况下,您如何更新此属性值?@DarinDimitrov:不,我们没有为用户提供此选项。(他不能自己更改国家)。