xeraphim
xeraphim

Reputation: 4645

ModelState.IsValid is true, but why?

I have the following Login-Model:

public class LoginDto
{
    private const string EmailRegex = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";

    public LoginDto(string email, string password)
    {
        this.Email = email;
        this.Password = password;
    }

    [Required(AllowEmptyStrings = false, ErrorMessage = "Email darf nicht leer sein.")]
    [RegularExpression(EmailRegex)]

    public string Email { get; set; }

    [Required(AllowEmptyStrings = false, ErrorMessage = "Passwort darf nicht leer sein.")]
    public string Password { get; set; }
}

Which is passed into my Controller Method via [FromBody]. I want to check, that both (Email and Password) are not empty by checking ModelState.IsValid:

[HttpPost("login")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[AllowAnonymous]
public async Task<IActionResult> PostLogin([FromBody] LoginDto loginData)
{
    if (!this.ModelState.IsValid) {
        return this.BadRequest(new Response(nameof(this.ModelState).ToCamelCase(), this.ModelState)                 {
            Status = ResponseStatus.Fail.ToString(),
            Code = StatusCodes.Status400BadRequest,
            Error = new ErrorObject { Code = "InvalidModelState", Message = "Submitted object doesn't pass it's validation check.", Target = "payload" }
        }
    ...
}

Unfortunately when I pass string.Empty as either Email or Password, the ModelState.IsValid is still true.

How can I achieve, that ModelState.IsValid is false when one of the properties is null or empty?

We're using .NET Core 3.

Thanks in advance

Upvotes: 1

Views: 249

Answers (3)

xeraphim
xeraphim

Reputation: 4645

I figured it out. I do NOT need to validate manually by checking this.ModelState.IsValid anymore in .Net Core 3.0. The middleware is handling it when having the [ApiController] attribute on the controller.

The [ApiController] attribute makes model validation errors automatically trigger an HTTP 400 response. Consequently, the following code is unnecessary in an action method:

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

Source: https://learn.microsoft.com/en-us/aspnet/core/web-api/index?view=aspnetcore-2.1#automatic-http-400-responses

Upvotes: 1

Tony
Tony

Reputation: 20102

Try to add [BindRequired] to your model like this

[Required(AllowEmptyStrings = false, ErrorMessage = "Email darf nicht leer sein.")]
[BindRequired]
[RegularExpression(EmailRegex)]
public string Email { get; set; }

[Required(AllowEmptyStrings = false, ErrorMessage = "Passwort darf nicht leer sein.")]
[BindRequired]
public string Password { get; set; }

You can read it more here

Upvotes: 0

Ricky Stam
Ricky Stam

Reputation: 2126

You could also try to add a MinLength(1) attribute.

Haven't tested it but should work i guess

Upvotes: 2

Related Questions