用于验证的数据注释,至少有一个必填字段?

发布于 2024-08-30 10:03:32 字数 124 浏览 10 评论 0原文

如果我有一个包含字段列表的搜索对象,我可以使用 System.ComponentModel.DataAnnotations 命名空间将其设置为验证搜索中至少有一个字段不为 null 或空吗?即所有字段都是可选的,但至少应输入一个字段。

If I have a search object with a list of fields, can I, using the System.ComponentModel.DataAnnotations namespace, set it up to validate that at least one of the fields in the search is not null or empty? i.e All the fields are optional but at least one should always be entered.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一张白纸 2024-09-06 10:03:32

我扩展了 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; }
}

I have extended Zhaph answer to support grouping of properties.

[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;
    }
}

Usage:

[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; }
}

And if you want to have 2 groups (or more):

[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; }
}
那一片橙海, 2024-09-06 10:03:32

我会为此创建一个自定义验证器 - 它不会为您提供客户端验证,而只会为您提供服务器端验证。

请注意,要使其工作,您需要使用 nullable 类型,因为值类型默认为 0false

首先创建一个新的验证器:

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 中。

请注意,您可以扩展它来检查返回的属性类型,或者如果您愿意的话,可以查找它们的属性以包含/排除验证 - 这是假设一个通用验证器不知道它正在验证的类型的任何信息。

I'd create a custom validator for this - it won't give you client side validation, just server side.

Note that for this to work, you'll need to be using nullable types, as value types will default to 0 or false:

First create a new validator:

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;
  }
}

You can then decorate your models with this:

[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; }
}

Then when you call ModelState.IsValid your validator will be called, and your message will be added to the ValidationSummary on your view.

Note that you could extend this to check for the type of property coming back, or look for attributes on them to include/exclude from validation if you want to - this is assuming a generic validator that doesn't know anything about the type it's validating.

蒲公英的约定 2024-09-06 10:03:32

这个问题已经很老了,但是从.NET 3.5(我相信)开始,IValidatableObject 可以帮助解决棘手的验证情况。您可以实现它来验证任意业务规则。在这种情况下,类似:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if (string.IsNullOrWhiteSpace(FieldOne) && string.IsNullOrWhiteSpace(FieldTwo))
        yield return new ValidationResult("Must provide value for either FieldOne or FieldTwo.", new string[] { "FieldOne", "FieldTwo" });
}

This question is pretty old, but as of .NET 3.5 (I believe), IValidatableObject can help with tricky validation situations. You can implement it to validate arbitrary business rules. In this case, something like:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if (string.IsNullOrWhiteSpace(FieldOne) && string.IsNullOrWhiteSpace(FieldTwo))
        yield return new ValidationResult("Must provide value for either FieldOne or FieldTwo.", new string[] { "FieldOne", "FieldTwo" });
}
离去的眼神 2024-09-06 10:03:32

.net 中的验证检查属性。假设您有两个字符串属性,field1 和 field2。只需添加一个这样的属性即可。

[RegularExpression("True|true", ErrorMessage = "At least one field must be given a value")] 
public bool Any => field1 != null || field2 != null;

详细信息请参见此处,以及 MinLength 等其他验证:https://stackoverflow.com/a/69621414/6742644

Validation in .net checks properties. Let's say you have two string properties, field1 and field2. Just add a property like this.

[RegularExpression("True|true", ErrorMessage = "At least one field must be given a value")] 
public bool Any => field1 != null || field2 != null;

Details here, with additional validations like MinLength etc: https://stackoverflow.com/a/69621414/6742644

养猫人 2024-09-06 10:03:32

如果您想对任何 .Net 类进行复杂的验证,而不用注释来对它们进行修饰,请查看 FluentValidation,或者对于 .Net 2.0,FluentValidation for 2.0

If you want to do complex validation against any .Net class, without litering them with annotations, look at FluentValidation, or for .Net 2.0, FluentValidation for 2.0

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文