Search code examples
asp.netentity-frameworkasp.net-corerazor-pages

why modelstate.isvalid always false despite the picture property in model getting assigned


I'm working on a razor pages project. I have an employee model which has a picture property of type byte array. Despite picture being assigned byte array when I check modelstate.isvalid, emp.picture is invalid here is my employee model and related code:

public class Employee
{
    public int Id { get; set; }

    [Required(ErrorMessage = "Please enter first name")]
    [DisplayName("First Name")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Please enter last name")]
    [DisplayName("Last Name")]
    public string LastName { get; set; }


    [Required(ErrorMessage = "Please enter age")]
    [Range(20, 60, ErrorMessage = "Valid age is between 20 to 60")]
    public int Age { get; set; }

    [Required(ErrorMessage = "Please select joining date")]
    [DisplayName("Joining Date")]
    [DataType(DataType.Date)]
    public DateTime JoiningDate { get; set; }

    [Required(ErrorMessage = "Please enter email address")]
    [EmailAddress]
    public string Email { get; set; }

    [Required(ErrorMessage = "Please enter phone number")]
    [DisplayName ("Phone No")]
    [Phone]
  
    public string PhoneNo { get; set; }
    public byte[] Picture { get; set; }

    public bool Gender { get; set; }
    public bool Active { get; set; } = true;

    [Required(ErrorMessage = "Please select a Department")]
    public int DepartmentId { get; set; }
    public Department? Department { get; set; }

    [NotMapped]
    public IFormFile ImageFile { get; set; }
}

    public async Task<IActionResult> OnPostAsync()
    {
       byte[] bytes;
        if (emp.ImageFile != null)
        {
            using (Stream fs = emp.ImageFile.OpenReadStream())
            {
                using (BinaryReader br = new BinaryReader(fs))
                {
                    bytes = br.ReadBytes((Int32)fs.Length);

                }
            }
            emp.Picture = bytes;
        }
      
        if (!ModelState.IsValid)
        {
            return Page();
        }
       
        _db.Employees.Add(emp);
        await _db.SaveChangesAsync();
        TempData["Success"] = "Employee created successfully....";
        return RedirectToPage("/Employees/Index");
    }
}

I am expecting that picture should have a value but I don't know why is isn't.


Solution

  • Model binding takes place before the code in your OnPostAsync method executes, and ModelState is not updated as a result of you assigning a value to the Picture property. You can use the ModelState.Remove method to remove the invalid entry after you are happy you have assigned a value to Picture:

    public async Task<IActionResult> OnPostAsync()
    {
        byte[] bytes;
        if (emp.ImageFile != null)
        {
            using (Stream fs = emp.ImageFile.OpenReadStream())
            {
                using (BinaryReader br = new BinaryReader(fs))
                {
                    bytes = br.ReadBytes((Int32)fs.Length);
    
                }
            }
            emp.Picture = bytes;
            ModelState.Remove("emp.Picture");
        }
          
        if (!ModelState.IsValid)
        {
            return Page();
        }
           
        _db.Employees.Add(emp);
        await _db.SaveChangesAsync();
        TempData["Success"] = "Employee created successfully....";
        return RedirectToPage("/Employees/Index");
    }