【问题标题】:How to put conditional Required Attribute into class property to work with WEB API?如何将条件必需属性放入类属性以使用 WEB API?
【发布时间】:2013-12-17 18:52:11
【问题描述】:

我只想把 conditionalRequired Attribute 这与 WEB API

一起使用

示例

public sealed class EmployeeModel
{
      [Required]
      public int CategoryId{ get; set; }
      public string Email{ get; set; } // If CategoryId == 1 then it is required
}

我正在通过 (ActionFilterAttribute)

使用模型状态验证

【问题讨论】:

    标签: c# asp.net-mvc-4 asp.net-web-api custom-attributes


    【解决方案1】:

    您可以实现自己的ValidationAttribute。也许是这样的:

    public class RequireWhenCategoryAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var employee = (EmployeeModel) validationContext.ObjectInstance;
            if (employee.CategoryId == 1)
                return ValidationResult.Success;
    
            var emailStr = value as string;
            return string.IsNullOrWhiteSpace(emailStr)
                ? new ValidationResult("Value is required.")
                : ValidationResult.Success;
        }
    }
    
    public sealed class EmployeeModel
    {
        [Required]
        public int CategoryId { get; set; }
        [RequireWhenCategory]
        public string Email { get; set; } // If CategoryId == 1 then it is required
    }
    

    这只是一个示例。它可能存在投射问题,我不确定这是解决此问题的最佳方法。

    【讨论】:

    • "我不确定这是解决这个问题的最佳方法。" 还有什么其他方法可以解决这个问题?
    • @ vcsjones :这是一个好方法,实际上我想避免控制器中的验证逻辑,因为这需要很多更改(根据更改要求),我不想这样做。
    • @ShubhajyotiGhosh, @ScottChamberlain:为了节省您的时间并获得一些灵活性,而不是为每个特定案例创建自定义验证属性,请查看 ExpressiveAnnotations。通过在这种情况下使用它,您可以使用以下属性注释Email 字段:[RequiredIf("CategoryId == 1")]
    • 其实这条评论是错误的:如果 CategoryId == 1 则不需要
    • 梦幻般的答案。救了我的命!谢谢。
    【解决方案2】:

    这是我的 2 美分。它会给你一个很好的消息,比如“当前的 AssigneeType 值 Salesman 需要AssigneeId”它也适用于枚举。

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class RequiredForAnyAttribute : ValidationAttribute
    {
        /// <summary>
        /// Values of the <see cref="PropertyName"/> that will trigger the validation
        /// </summary>
        public string[] Values { get; set; }
    
        /// <summary>
        /// Independent property name
        /// </summary>
        public string PropertyName { get; set; }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var model = validationContext.ObjectInstance;
            if (model == null || Values == null)
            {
                return ValidationResult.Success;
            }
    
            var currentValue = model.GetType().GetProperty(PropertyName)?.GetValue(model, null)?.ToString();
            if (Values.Contains(currentValue) && value == null)
            {
                var propertyInfo = validationContext.ObjectType.GetProperty(validationContext.MemberName);
                return new ValidationResult($"{propertyInfo.Name} is required for the current {PropertyName} value {currentValue}");
            }
            return ValidationResult.Success;
        }
    }
    

    这样使用

    public class SaveModel {
        [Required]
        public AssigneeType? AssigneeType { get; set; }
    
        [RequiredForAny(Values = new[] { nameof(AssigneeType.Salesman) }, PropertyName = nameof(AssigneeType))]
        public Guid? AssigneeId { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-03
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 2018-06-27
      • 2019-08-18
      • 1970-01-01
      • 2013-04-04
      相关资源
      最近更新 更多