MVC2:具有两个字段依赖性的验证(数据注释)

时间:2010-09-02 14:13:15

标签: asp.net-mvc-2

实施例: 我们有一个条件字段。 此条件字段是一个单选按钮,其中包含以下两个值“是”和“否”。 让我们说这个radiobutton的名字是“AAA”。

仅当另一个单选按钮字段“BBB”设置为“是”时,才应显示该条件字段“AAA”。 (单选按钮“BBB”的值也是“是”而没有“)。

但条件字段“AAA”应显示为NO预设值,表示首次显示字段时应设置为“yes”或“no”。

问题的发生是基于以下要求:当(非条件)字段“BBB”设置为“是”时,仅需要条件字段“AAA” - 并且当设置字段“BBB”时不需要“不”。

(听起来,我没有听到关于if语句的任何内容,或者?但是继续阅读并继续阅读......)

相信我,当我们使用“Modelstate”时,解决这个问题对我来说不是问题 - 但我们在这里讨论的验证(数据注释)如下所示:

public class Input1FormModel 
{
     [Required(ErrorMessageResourceName="Error_Field_AAA_Empty",
               ErrorMessageResourceType=typeof(Resources.MyDialog))]
     public int AAA { get; set; }
}

我完全理解这些代码行 - 我相信; - )

...

//property limits
public int UpperBound { get { return DateTime.Now.Year; } }
public int LowerBound { get { return 1900; } }

...

[NotNullValidator]
[PropertyComparisonValidator("LowerBound", ComparisonOperator.GreaterThan)]
[PropertyComparisonValidator("UpperBound", ComparisonOperator.LessThanEqual)]
public int? XYZ { get; set; }

但是,如何解决上述依赖性(AAA< -BBB)?

将“return DateTime.Now.Year;”更改为函数调用,该函数首先检查另一个字段并返回true或false?但是如何获取其他字段的值?

2 个答案:

答案 0 :(得分:1)

您可能需要使用IDataErrorInfo。

请参阅this question,我回答了这个问题:

结帐IDataErrorInfo,我问过这个问题IDataErrorInfo vs. DataAnnotations

答案 1 :(得分:0)

您可以使用数据注释来执行此操作,但注释需要在类级别而不是在属性级别上操作,因为validationattributes适用于单个属性。

这是我创建的一个例子,因为邮政编码是可选的,如果人们说他们在新西兰,则不需要说明,但这在澳大利亚是强制性的。此复合验证使用整个模型作为输入值,并使用反射来比较从数据注释传入的属性名称的值。

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class NZPostcodeAttribute : ValidationAttribute
{
    public const string _defaultErrorMessage = "Postcode and State are required for Australian residents";
    private readonly object _typeId = new object();

    public NZPostcodeAttribute(string countryProperty, string postcodeProperty, string stateProperty)
    {
        CountryProperty = countryProperty;
        PostcodeProperty = postcodeProperty;
        StateProperty = stateProperty;
    }

    public string CountryProperty { get; private set; }
    public string StateProperty { get; private set; }
    public string PostcodeProperty { get; private set; }

    public override object TypeId
    {
        get
        {
            return _typeId;
        }
    }

    public override string FormatErrorMessage(string name)
    {
        return _defaultErrorMessage;
    }

    public override bool IsValid(object value)
    {
        PropertyDescriptorCollection props = TypeDescriptor.GetProperties(value);
        object countryValue = props.Find(CountryProperty, true).GetValue(value);
        object postcodeValue = props.Find(PostcodeProperty, true).GetValue(value);
        object stateValue = props.Find(StateProperty, true).GetValue(value);

        string countryString = countryValue == null ? "" : countryValue.ToString();
        string postcodeString = postcodeValue == null ? "" : postcodeValue.ToString();
        string stateString = stateValue == null ? "" : stateValue.ToString();


        bool isValid = true;

        if (countryString.ToString().ToLower() == "australia")
        {
            if (String.IsNullOrEmpty(postcodeString) || String.IsNullOrEmpty(stateString))
            {
                isValid = false;
            }
        }
        if (!String.IsNullOrEmpty(postcodeString))
        {
            string isNumeric = "^[0-9]+";
            if (!Regex.IsMatch(postcodeString, isNumeric))
                isValid = false;
        }
        return isValid;
    }
}

如果要将其应用于模型,则需要在模型的类级别上完成(请参阅顶部的标志AttributeTargets.Class)。

按如下方式进行:

[NZPostcode("Country", "Postcode", "State")]
public class UserRegistrationModel 
{....

您需要将validation属性指向属性名称。也可以为此添加客户端验证,但这本身就是一篇完整的文章。

您可以轻松地将上述内容调整为您的方案。

相关问题