Asp.net

驗證的數據註釋,至少一個必填欄位?

  • April 26, 2010

如果我有一個帶有欄位列表的搜尋對象,我可以使用system.componentmodel.dataannotations命名空間,設置它以驗證搜尋中的至少一個欄位不是null還是空?即所有欄位都是可選的,但至少應始終輸入一個欄位。

我會為此創建一個自定義驗證器 - 它不會給您客戶端驗證,只是伺服器端。

請注意,為此工作,您需要使用nullable類型,因為預設0值為false

首先創建一個新的驗證:

using System.ComponentModel.DataAnnotations;
using System.Reflection;

// This is a class-level attribute, doesn't make sense at the property level
[AttributeUsage(AttributeTargets.Class)]
public class AtLeastOnePropertyAttribute : ValidationAttribute
{
 // Have to override IsValid
 public override bool IsValid(object value)
 {
   //  Need to use reflection to get properties of "value"...
   var typeInfo = value.GetType();

   var propertyInfo = typeInfo.GetProperties();

   foreach (var property in propertyInfo)
   {
     if (null != property.GetValue(value, null))
     {
       // We've found a property with a value
       return true;
     }
   }

   // All properties were null.
   return false;
 }
}

然後,您可以使用此裝飾你的機型:

[AtLeastOneProperty(ErrorMessage="You must supply at least one value")]
public class SimpleTest
{
   public string StringProp { get; set; }
   public int? Id { get; set; }
   public bool? BoolProp { get; set; }
}

然後當你呼叫ModelState.IsValid你的驗證將被呼叫,和您的郵件將被添加到在ValidationSummary對你的看法。

請注意,您可以擴展此檢查財產回來,或者尋找它們的屬性,包括類型的驗證/排除如果你想 - 這是假設一個通用的驗證,不知道它的驗證類型什麼。

我已經擴展Zhaph回答支持性的分組。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class AtLeastOnePropertyAttribute : ValidationAttribute
{
   private string[] PropertyList { get; set; }

   public AtLeastOnePropertyAttribute(params string[] propertyList)
   {
       this.PropertyList = propertyList;
   }

   //See http://stackoverflow.com/a/1365669
   public override object TypeId
   {
       get
       {
           return this;
       }
   }

   public override bool IsValid(object value)
   {
       PropertyInfo propertyInfo;
       foreach (string propertyName in PropertyList)
       {
           propertyInfo = value.GetType().GetProperty(propertyName);

           if (propertyInfo != null && propertyInfo.GetValue(value, null) != null)
           {
               return true;
           }
       }

       return false;
   }
}

用法:

[AtLeastOneProperty("StringProp", "Id", "BoolProp", ErrorMessage="You must supply at least one value")]
public class SimpleTest
{
   public string StringProp { get; set; }
   public int? Id { get; set; }
   public bool? BoolProp { get; set; }
}

如果你想擁有2組(或更多):

[AtLeastOneProperty("StringProp", "Id", ErrorMessage="You must supply at least one value")]
[AtLeastOneProperty("BoolProp", "BoolPropNew", ErrorMessage="You must supply at least one value")]
public class SimpleTest
{
   public string StringProp { get; set; }
   public int? Id { get; set; }
   public bool? BoolProp { get; set; }
   public bool? BoolPropNew { get; set; }
}

引用自:https://stackoverflow.com/questions/2712511