0

I am using ASP.NET Core 5, .NET 5 version 5.0.100-rc.1.20452.10 . I have a model need validate

/// <summary>
/// Model của form dùng khi admin thêm mới người dùng từ giao diện quản trị.
/// </summary>
public class AddUserForm
{
    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    public string Password { get; set; }        
        
    public string About { get; set; }

    public string Fullname { get; set; }
    public string AliasName { get; set; }
    public string SecondMobile { get; set; }
    public string PhoneNumber { get; set; }

    [DataType(DataType.Upload)]
    public IFormFile file { get; set; }
}

The rule of validation is must have (required) 1 of 2 fields: About or AliasName . It means

  1. Has About, no AliasName, it is ok.

  2. No About, has AliasName, it is ok.

  3. Has About, has AliasName, it is ok.

  4. No About, no AliasName, it is not ok.

controller

/// <summary>
/// Admin Thêm mới người dùng từ giao diện quản trị.
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
[HttpPost]
public async Task<ActionResult<string>> AddUser([FromForm] AddUserForm form)
{
    if (ModelState.IsValid)
    {
        ApplicationUser user = new ApplicationUser();
        // https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.usermanager-1.createasync?view=aspnetcore-3.1
        // user.PasswordHash = HashPassword()
        if (String.IsNullOrEmpty(form.Email))
        {
            user.Email = form.Email;
        }
        user.EmailConfirmed = true;

        if (String.IsNullOrEmpty(form.Email))
        {
            user.NormalizedEmail = form.Email.ToUpper();
        }
        if (String.IsNullOrEmpty(form.About))
        {
            user.About = form.About;
        }
        if (String.IsNullOrEmpty(form.AliasName))
        {
            user.AliasName = form.AliasName;
        }
        if (String.IsNullOrEmpty(form.Fullname))
        {
            user.Fullname = form.Fullname;
        }
        if (String.IsNullOrEmpty(form.PhoneNumber))
        {
            user.PhoneNumber = form.PhoneNumber;
        }
        if (String.IsNullOrEmpty(form.SecondMobile))
        {
            user.SecondMobile = form.SecondMobile;
        }
        if (String.IsNullOrEmpty(form.Email))
        {
            user.UserName = form.Email;
        }
        //FIXME: Chưa có phần thêm avatar.
        if (form.file != null)
        {
            // Ghi file. Làm tương tự khi thêm Asset.
            if (IsImageFile(form.file))
            {
                string imgPath = await WriteFile(form.file);
                user.Avatar = imgPath;
            }
            else
            {
                return BadRequest(new { message = "Invalid file extension" });
            }
        }
        string pass = form.Password;
        user.Created = DateTime.Now;
        user.Modified = DateTime.Now;
        await _userManger.CreateAsync(user, pass);
        await _db.SaveChangesAsync();
        return Ok(user);
    }
    else
    {
        return BadRequest(ModelState);
    }            
}

How to achieve this rule of validation, I prefer use annotation.

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Vy Do
  • 46,709
  • 59
  • 215
  • 313
  • 6
    You'll need to write a custom validation attribute - this should get you started https://stackoverflow.com/a/41901736/426894 – asawyer Sep 18 '20 at 02:19

1 Answers1

1

Try to use the following code to create a custom validation method:

public class AddUserForm
    {
        [Required]
        [EmailAddress]
        public string Email { get; set; }

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

        public string About { get; set; }

        public string Fullname { get; set; }

        [RequiredIfHasValue("About", ErrorMessage ="About or AliasName is Required")]
        public string AliasName { get; set; }
        public string SecondMobile { get; set; }
        public string PhoneNumber { get; set; }
    }

    public class RequiredIfHasValueAttribute : ValidationAttribute
    {
        private readonly string _comparisonProperty;

        public RequiredIfHasValueAttribute(string comparisonProperty)
        {
            _comparisonProperty = comparisonProperty;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            ErrorMessage = ErrorMessageString;

            //get entered alias name
            var aliasName = (string)value;
            var property = validationContext.ObjectType.GetProperty(_comparisonProperty);
            if (property == null)
                throw new ArgumentException("Property with this name not found");
            //get the about value
            var aboutValue = (string)property.GetValue(validationContext.ObjectInstance);

            if (aliasName == null && aboutValue == null)
                return new ValidationResult(ErrorMessage);
             
            return ValidationResult.Success;
        }
    }
 
Zhi Lv
  • 18,845
  • 1
  • 19
  • 30