有条件地使MVC类属性/类成为必需

时间:2011-08-31 23:59:54

标签: c# asp.net-mvc asp.net-mvc-3 validation data-annotations

我有一个Address类,用于模型中的MailingAddress和BillingAddress属性。我希望MailingAddress是必需的,但不是BillingAddress,但我没有看到使用DataAnnotations执行此操作的方法。

如果我能够在MailingAddress属性上设置[Required]属性并以某种方式定义Address类应该如何处理所需逻辑的逻辑,我觉得这将是一个简单的解决方案。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

如果您的问题是如何在您自己的逻辑中使用Required属性,那么答案就是使用反射。如果那不是你的问题,请原谅我。

从相关类型中获取所有属性,然后查看它是否使用RequiredAttribute进行修饰。

class ParentClass
{
      [Required]
      public Address MailingAddress { get; set; }

      public Address BillingAddress { get; set; }
}

(...)

Type t = typeof(ParentClass);

foreach (PropertyInfo p in t.GetProperties())
{
    Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
    if (a != null)
    {
          // The property is required, apply your logic
    }
    else
    {
          // The property is not required, apply your logic
    }
}

编辑:修正了代码中的拼写错误

编辑2:扩展代码示例

答案 1 :(得分:0)

这只是一个奇怪的怪癖,突然出现在我脑海中:

一个简单的解决方案可能是将Address子类化为OptionalAddress。

我认为必需属性不会继承到子类。

如果需要,还会想到

[AttributeUsage (Inherited = False)]

更多MVCish解决方案可能是实现自定义模型绑定器(完全未经测试):

public override object BindModel(ControllerContext controllerContext,
    ModelBindingContext bindingContext)
        {
            var address = base.BindModel(controllerContext, bindingContext) as Address;
            if (bindingContext.ModelName.EndsWith("BillingAddress"))
            {
                foreach (PropertyInfo p in address.GetType().GetProperties())
                {
                Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
                if (a != null 
                    && propertyInfo.GetValue(address, null) == null 
                    && bindingContext.ModelState[bindingContext.ModelName 
                       + "." + p.Name].Errors.Count == 1)
                {
                    bindingContext.ModelState[bindingContext.ModelName + "." + p.Name].Errors.Clear();
                }
            }
            return address;
        }

答案 2 :(得分:0)

此前提出的问题提供了许多选项:

ASP.NET MVC Conditional validation

您是否需要在客户端进行此验证?

IValidateableObject将与您现有的任何属性结合使用,并可提供额外的自定义验证。