2.7: Validating User Submitted Data

Right now we have a problem - we have no validation for what the user submits. A user could create a new account with a blank username and password:

BlankRegister
BlankDatabase

Add validation attributes to the UserForRegister class:

public class UserForRegister
{
    [Required]
    public string Username { get; set; }

    [Required]
    [StringLength(8, MinimumLength = 4, ErrorMessage = "Password must be between 4 and 8 characters.")]
    public string Password { get; set; }
}

Check validation in the controller (whether or not the ModelState is valid):

[HttpPost("Register")]
public async Task<IActionResult> Register([FromBody] UserForRegister userForRegister)
{
    if(!ModelState.IsValid)
        return BadRequest(ModelState);

    userForRegister.Username = userForRegister.Username.ToLower();

    if (await _authService.UserExists(userForRegister.Username))
        return BadRequest("Username is already taken");

    var userToCreate = new User
    {
        Username = userForRegister.Username
    };

    var createUser = await _authService.Register(userToCreate, userForRegister.Password);

    return StatusCode(201);
}

Let's test to see what we get if we try to submit blank user data now:

BlankRegister2

Cool! We're getting a 400 Bad Request along with the ModelState - providing us with a JSON object of the errors.

However, remember our check to see if a user already exists? We weren't adding that to the ModelState - we were just passing along a BadRequest with that one error. Let's improve that by rearranging our code by adding the 'user already exists' error to the ModelState.

We'll also add a null check to make sure the user isn't sending along an empty username.

[HttpPost("Register")]
public async Task<IActionResult> Register([FromBody] UserForRegister userForRegister)
{
    if (!string.IsNullOrEmpty(userForRegister.Username))
        userForRegister.Username = userForRegister.Username.ToLower();

    if (await _authService.UserExists(userForRegister.Username))
        ModelState.AddModelError("Username", "Username already exists");

    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    var userToCreate = new User
    {
        Username = userForRegister.Username
    };

    var createUser = await _authService.Register(userToCreate, userForRegister.Password);

    return StatusCode(201);
}

Let's check Postman again by sending another request with an already created user:

UserExistsModelState

Last updated