Asp.Net MVC验证相关字段
我目前正在尝试进行MVC验证,遇到了一些问题,根据另一个字段的值需要一个字段。下面是一个例子(我还没有弄清楚)-如果PaymentMethod==“check”,那么ChequeName应该是必需的,否则它可以通过Asp.Net MVC验证相关字段,asp.net,asp.net-mvc,validation,Asp.net,Asp.net Mvc,Validation,我目前正在尝试进行MVC验证,遇到了一些问题,根据另一个字段的值需要一个字段。下面是一个例子(我还没有弄清楚)-如果PaymentMethod==“check”,那么ChequeName应该是必需的,否则它可以通过 [Required(ErrorMessage = "Payment Method must be selected")] public override string PaymentMethod { get; set; } [Required(ErrorMessage = "Che
[Required(ErrorMessage = "Payment Method must be selected")]
public override string PaymentMethod
{ get; set; }
[Required(ErrorMessage = "ChequeName is required")]
public override string ChequeName
{ get; set; }
我正在为[Required]使用System.ComponentModel.DataAnnotations,并扩展了ValidationAttribute以尝试使其正常工作,但我无法传递变量来进行验证(下面的扩展)
实施:
[JEPaymentDetailRequired(PaymentSelected = PaymentMethod, PaymentType = "Cheque", ErrorMessage = "Cheque name must be completed when payment type of cheque")]
有人有过这种验证的经验吗?将其写入控制器会更好吗
谢谢您的帮助。我将在模型中编写验证逻辑,而不是在控制器中。控制器应仅处理视图和模型之间的交互。由于模型需要验证,我认为它被广泛认为是验证逻辑的场所 对于依赖于另一个属性或字段的值的验证,我(不幸地)不知道如何完全避免在模型中为此编写一些代码,如Wrox ASP.NET MVC手册中所示,类似于:
public bool IsValid
{
get
{
SetRuleViolations();
return (RuleViolations.Count == 0);
}
}
public void SetRuleViolations()
{
if (this.PaymentMethod == "Cheque" && String.IsNullOrEmpty(this.ChequeName))
{
RuleViolations.Add("Cheque name is required", "ChequeName");
}
}
以声明的方式进行所有验证将非常好。我相信您可以创建一个
RequiredDependentAttribute
,但这只能处理这一类逻辑。稍微复杂一点的东西还需要另一个非常具体的属性,等等,这很快就会变得疯狂。你的问题可以相对简单地通过使用例如
如果除了服务器上的模型验证之外,还需要客户端验证,我认为最好的方法是自定义验证属性(如Jaroslaw建议的)。我在这里包括了我使用的那个的来源 自定义属性:
public class RequiredIfAttribute : DependentPropertyAttribute
{
private readonly RequiredAttribute innerAttribute = new RequiredAttribute();
public object TargetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue) : base(dependentProperty)
{
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(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 && TargetValue == null) ||
(dependentvalue != null && dependentvalue.Equals(TargetValue)))
{
// match => means we should try validating this field
if (!innerAttribute.IsValid(value))
// validation failed - return an error
return new ValidationResult(ErrorMessage, new[] { validationContext.MemberName });
}
}
return ValidationResult.Success;
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "requiredif"
};
var depProp = BuildDependentPropertyId(DependentProperty, 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!)
var targetValue = (TargetValue ?? "").ToString();
if (TargetValue != null)
if (TargetValue is bool)
targetValue = targetValue.ToLower();
rule.ValidationParameters.Add("dependentproperty", depProp);
rule.ValidationParameters.Add("targetvalue", targetValue);
yield return rule;
}
}
[Required]
public bool IsEmailGiftCertificate { get; set; }
[RequiredIf("IsEmailGiftCertificate", true, ErrorMessage = "Please provide Your Email.")]
public string YourEmail { get; set; }
使用属性装饰属性:
public class RequiredIfAttribute : DependentPropertyAttribute
{
private readonly RequiredAttribute innerAttribute = new RequiredAttribute();
public object TargetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue) : base(dependentProperty)
{
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(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 && TargetValue == null) ||
(dependentvalue != null && dependentvalue.Equals(TargetValue)))
{
// match => means we should try validating this field
if (!innerAttribute.IsValid(value))
// validation failed - return an error
return new ValidationResult(ErrorMessage, new[] { validationContext.MemberName });
}
}
return ValidationResult.Success;
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "requiredif"
};
var depProp = BuildDependentPropertyId(DependentProperty, 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!)
var targetValue = (TargetValue ?? "").ToString();
if (TargetValue != null)
if (TargetValue is bool)
targetValue = targetValue.ToLower();
rule.ValidationParameters.Add("dependentproperty", depProp);
rule.ValidationParameters.Add("targetvalue", targetValue);
yield return rule;
}
}
[Required]
public bool IsEmailGiftCertificate { get; set; }
[RequiredIf("IsEmailGiftCertificate", true, ErrorMessage = "Please provide Your Email.")]
public string YourEmail { get; set; }
只需使用Codeplex上提供的万无一失的验证库: 它支持以下“requiredif”验证属性/装饰:
[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]
开始很容易:
仔细想想。。。如何设置PaymentSelected=PaymentMethod?你应该得到一个错误,因为PaymentMethod不是一个常量表达式。嗨,Min,你是对的。我原以为我可以这样做,但没用。我只是想展示我所做的尝试,但也评论说它不允许我传递变量。感谢djuth,我已经获取了一个ModelStateDictionary并在模型中对此进行了验证,然后将该dictionary传递回控制器以合并到ModelState中。似乎做到了这一点,并允许我做一些编程工作-不太好,只是做一个声明每个属性,但至少我可以在一个地方得到一切。如果每个属性tho有多个错误,我不确定这将如何进行。我知道这个答案已经有2年了,但我正在尝试让它起作用,基本上它会启动依赖属性的验证,无论第一个属性的值是什么。任何帮助都将不胜感激。
[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]