I've been looking around and I think my solution is just fine but somehow the ModelState.IsValid
property is always true
.
Consider the following code snippets:
[Route("address")]
[HttpPut]
[ResponseType(typeof(UserViewModel))]
public IHttpActionResult UpdateAddress([FromBody] UpdateAdressValidationModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// irrelevant code omitted
}
[TestMethod]
public void UpdateAddress_WithoutStreet_ReturnsHttpCode400()
{
var userController = new UserController(new UserRepository(_context));
var addressInfo = new UpdateAdressValidationModel
{
City = "Ghent",
};
var response = userController.UpdateAddress(addressInfo) as BadRequestResult;
Assert.IsNotNull(response);
}
public class UpdateAdressValidationModel
{
[Required]
public string Street { get; set; }
[Required]
public int? Number { get; set; }
[Required]
public string Bus { get; set; }
[Required]
public int? PostalCode { get; set; }
[Required]
public string City { get; set; }
}
Still gives me a valid modelstate, even though it clearly shows that the required properties are null
.
What am I overlooking?
Note that manually adding
Validator.ValidateObject(model, new ValidationContext(model));
at the top of the UpdateAddress
method throws a ValidationException
on the Street
field so it can in fact validate the model. Question remains: why doesn't it automatically?
Furthermore, this isn't applicable because my model
isn't null
.
Nothing in your execution path causes validation to occur. That's done as part of the model binding, which you aren't doing as you're manually creating your model instance.
Turns out that this answer had the right idea but the solution didn't quite fit.
Which is correct, but the proposed solution throws a ValidationException instead of simply setting the
IsValid
property tofalse
.Luckily, there is a specific method that can do this:
ApiController.Validate()
. By adding these lines to my Unit Test it sets theModelState
to invalid and does not throw an exception.