Je veux juste mettre attribut obligatoire conditionnel qui fonctionne avec API WEB
Exemple
public sealed class EmployeeModel
{
[Required]
public int CategoryId{ get; set; }
public string Email{ get; set; } // If CategoryId == 1 then it is required
}
J'utilise la validation de l'état du modèle via (ActionFilterAttribute)
Vous pouvez implémenter votre propre ValidationAttribute
. Peut-être quelque chose comme ça:
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
}
Ce n'est qu'un échantillon. Il peut y avoir des problèmes de casting, et je ne suis pas sûr que ce soit la meilleure approche pour résoudre ce problème.
Voici mes 2 cents. Cela vous donnera un joli message comme "AssigneeId est requis pour la valeur actuelle de AssigneeType Salesman" Cela fonctionne aussi pour les énumérations.
[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;
}
}
Utilisez-le comme ça
public class SaveModel {
[Required]
public AssigneeType? AssigneeType { get; set; }
[RequiredForAny(Values = new[] { nameof(AssigneeType.Salesman) }, PropertyName = nameof(AssigneeType))]
public Guid? AssigneeId { get; set; }
}