web-dev-qa-db-ja.com

条件付き必須属性をクラスプロパティに入れてWEB APIを操作する方法

条件付き必須属性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)によるモデル状態の検証を使用しています

21

独自の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.IsNullOrEmpty(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
}

これは単なるサンプルです。キャストの問題がある可能性があり、これがこの問題を解決するための最良のアプローチであるかどうかはわかりません。

36
vcsjones

これが私の2セントです。 「AssigneeIdは現在のAssigneeType値Salesmanに必要です」のような素敵なメッセージが表示されます。これは列挙型でも機能します。

[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; }
}
2
Kautsky Lozano