wootscootinboogie
wootscootinboogie

Reputation: 8695

.NET Core Web API model validation

I have a method that generically looks like

    public IActionResult SomeAction(Guid id, [FromBody] Request request)
    {
       //bunch of other stuff left out
       AnotherObject obj = Mapper.Map(request);
      if (ModelState.IsValid) {//only validation errors on the request object are found
//obj validation errors are ignored
}
    }

In the Request class I'm using DataAnnotations to test the model state and these are working fine. However, inside of AnotherObject I'm also using DataAnnotations and when I test ModelState in this function, .NET sees the validation errors from the Request object, but not in the mapped object.

The callers of this endpoint don't know about AnotherObject, and don't need to. Is there a way to get .NET to respect the validations on an object that is created inside of a controller action and not passed in?

Upvotes: 2

Views: 4559

Answers (2)

John Nyingi
John Nyingi

Reputation: 1110

The ModelState validates the Model when it converts the JSON to Type Request. The ModelState hence forth validates against null values and mismatching types. When you map request to obj no invocation to ModelState occurs.

Hence, using:

if (ModelState.IsValid) {
  AnotherObject obj = Mapper.Map(request);
}

validates the Model while mapping... You really don't need two ModelState Validators

Upvotes: 1

Bas
Bas

Reputation: 2038

You can use the Validator object to manually test objects:

var obj = Mapper.Map(request);
var context = new ValidationContext(obj, serviceProvider: null, items: null);
var results = new List<ValidationResult>();

var isValid = Validator.TryValidateObject(obj, context, results);

See this short tutorial for more information.

Note that this does not work recursively, depending on the complexity of AnotherObject, you may need to use Reflection to recurse through the object yourself.

Upvotes: 6

Related Questions