首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用OR条件的条件RequiredIf条件

使用OR条件的条件RequiredIf条件
EN

Stack Overflow用户
提问于 2020-05-10 14:58:21
回答 1查看 633关注 0票数 0

我正在上下面的课:

代码语言:javascript
复制
public class CustomerNameSearchRequest
{
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    public string StreetAddress { get; set; }

    public string City { get; set; }

    public string State { get; set; }

    public string ZipCode { get; set; }

}

我有以下条件:The LastName property is required IF the FirstName is null OR StreetAddress is null OR City is null OR State is null OR ZipCode is null

我已经查找了堆栈溢出,并且习惯于遵循RequiredIf验证属性。

代码语言:javascript
复制
/// <summary>
/// Provides conditional validation based on related property value.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public sealed class RequiredIfAttribute : ValidationAttribute
{
    #region Properties

    /// <summary>
    /// Gets or sets the other property name that will be used during validation.
    /// </summary>
    /// <value>
    /// The other property name.
    /// </value>
    public string OtherProperty { get; private set; }

    /// <summary>
    /// Gets or sets the display name of the other property.
    /// </summary>
    /// <value>
    /// The display name of the other property.
    /// </value>
    public string OtherPropertyDisplayName { get; set; }

    /// <summary>
    /// Gets or sets the other property value that will be relevant for validation.
    /// </summary>
    /// <value>
    /// The other property value.
    /// </value>
    public object OtherPropertyValue { get; private set; }

    /// <summary>
    /// Gets or sets a value indicating whether other property's value should match or differ from provided other property's value (default is <c>false</c>).
    /// </summary>
    /// <value>
    ///   <c>true</c> if other property's value validation should be inverted; otherwise, <c>false</c>.
    /// </value>
    /// <remarks>
    /// How this works
    /// - true: validated property is required when other property doesn't equal provided value
    /// - false: validated property is required when other property matches provided value
    /// </remarks>
    public bool IsInverted { get; set; }

    /// <summary>
    /// Gets a value that indicates whether the attribute requires validation context.
    /// </summary>
    /// <returns><c>true</c> if the attribute requires validation context; otherwise, <c>false</c>.</returns>
    public override bool RequiresValidationContext
    {
        get { return true; }
    }

    #endregion

    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="RequiredIfAttribute"/> class.
    /// </summary>
    /// <param name="otherProperty">The other property.</param>
    /// <param name="otherPropertyValue">The other property value.</param>
    public RequiredIfAttribute(string otherProperty, object otherPropertyValue)
        : base("'{0}' is required because '{1}' has a value {3}'{2}'.")
    {
        this.OtherProperty = otherProperty;
        this.OtherPropertyValue = otherPropertyValue;
        this.IsInverted = false;
    }

    #endregion

    /// <summary>
    /// Applies formatting to an error message, based on the data field where the error occurred.
    /// </summary>
    /// <param name="name">The name to include in the formatted message.</param>
    /// <returns>
    /// An instance of the formatted error message.
    /// </returns>
    public override string FormatErrorMessage(string name)
    {
        return string.Format(
            CultureInfo.CurrentCulture,
            base.ErrorMessageString,
            name,
            this.OtherPropertyDisplayName ?? this.OtherProperty,
            this.OtherPropertyValue,
            this.IsInverted ? "other than " : "of ");
    }

    /// <summary>
    /// Validates the specified value with respect to the current validation attribute.
    /// </summary>
    /// <param name="value">The value to validate.</param>
    /// <param name="validationContext">The context information about the validation operation.</param>
    /// <returns>
    /// An instance of the <see cref="T:System.ComponentModel.DataAnnotations.ValidationResult" /> class.
    /// </returns>
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (validationContext == null)
        {
            throw new ArgumentNullException("validationContext");
        }

        PropertyInfo otherProperty = validationContext.ObjectType.GetProperty(this.OtherProperty);
        if (otherProperty == null)
        {
            return new ValidationResult(
                string.Format(CultureInfo.CurrentCulture, "Could not find a property named '{0}'.", this.OtherProperty));
        }

        object otherValue = otherProperty.GetValue(validationContext.ObjectInstance);

        // check if this value is actually required and validate it
        if (!this.IsInverted && object.Equals(otherValue, this.OtherPropertyValue) ||
            this.IsInverted && !object.Equals(otherValue, this.OtherPropertyValue))
        {
            if (value == null)
            {
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }

            // additional check for strings so they're not empty
            string val = value as string;
            if (val != null && val.Trim().Length == 0)
            {
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }
        }

        return ValidationResult.Success;
    }
}

但是,如果我要实现以下多个RequiredIf属性:

代码语言:javascript
复制
[RequiredIf(nameof(FirstName), null)]
[RequiredIf(nameof(StreetAddress), null)]
[RequiredIf(nameof(City), null)]
[RequiredIf(nameof(State), null)]
[RequiredIf(nameof(ZipCode), null)]
public string LastName { get; set; }

不管如何,它都将强制LastName属性具有一个值。如何在RequiredIf属性中实现OR条件?还有更好的代码可以帮助我实现我的需求吗?

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-10 16:04:01

可以将属性更改为接受具有以下字段和值对的字符串数组:

代码语言:javascript
复制
    public class CustomerNameSearchRequest
    {
        public string FirstName { get; set; }

        [RequiredIf(new string[] {
            "FirstName, !null",
            "StreetAddress, !null",
            "City, !null",
            "State, !null",
            "ZipCode, !null"
        })]
        public string LastName { get; set; }

        public string StreetAddress { get; set; }

        public string City { get; set; }

        public string State { get; set; }

        public string ZipCode { get; set; }
    }

并以下列方式创建RequiredIf属性:

代码语言:javascript
复制
    public class RequiredIfAttribute : ValidationAttribute
    {
        private const string DefaultErrorMessageFormatString = "The {0} field is required.";
        private readonly string[] _dependentProperties;

        public RequiredIfAttribute(string[] dependentProperties)
        {
            _dependentProperties = dependentProperties;
            ErrorMessage = DefaultErrorMessageFormatString;
        }

        private bool IsValueRequired(string checkValue, object currentValue)
        {
            if (checkValue.Equals("!null", StringComparison.InvariantCultureIgnoreCase))
            {
                return currentValue != null;
            }

            return checkValue.Equals(currentValue);
        }

        protected override ValidationResult IsValid(object value, ValidationContext context)
        {
            object instance = context.ObjectInstance;
            Type type = instance.GetType();
            bool valueRequired = false;

            foreach (string s in _dependentProperties)
            {
                var fieldValue = s.Split(',').ToList().Select(k => k.Trim()).ToArray();

                object propertyValue = type.GetProperty(fieldValue[0]).GetValue(instance, null);

                valueRequired = IsValueRequired(fieldValue[1], propertyValue);
            }

            if (valueRequired)
            {
                return value != null
                    ? ValidationResult.Success
                    : new ValidationResult(context.DisplayName + " required. ");
            }
            return ValidationResult.Success;
        }
    }

2.验证字段是否需要(不)的IsValueRequired方法

代码语言:javascript
复制
    private bool IsValueRequired(string checkValue, object currentValue)
    {
        if (checkValue.Equals("!null", StringComparison.InvariantCultureIgnoreCase))
        {
            return currentValue != null;
        }

        return checkValue.Equals(currentValue);
    }

3. IsValid检查字段为空还是不为空:

代码语言:javascript
复制
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        object instance = context.ObjectInstance;
        Type type = instance.GetType();
        bool valueRequired = false;

        foreach (string s in _dependentProperties)
        {
            var fieldValue = s.Split(',').ToList().Select(k => k.Trim()).ToArray();

            object propertyValue = type.GetProperty(fieldValue[0]).GetValue(instance, null);

            valueRequired = IsValueRequired(fieldValue[1], propertyValue);
        }

        if (valueRequired)
        {
            return value != null
                ? ValidationResult.Success
                : new ValidationResult(context.DisplayName + " required. ");
        }
        return ValidationResult.Success;
    }

来源:

  1. https://www.codeproject.com/Questions/5161571/How-to-use-data-annotation-to-check-for-two-values;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61714030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档