1

When posting JSON to Web API, not only does it get deserialized automatically, one can also use model validation like

// ItemPostRequest
class ItemPostRequest {
    [Required] // this will automatically be validated and errors created if it is missing
    public string Description { get; set; }
}

However in my case, I only have a string containing JSON. I can deserialize it using JsonSerializer.Deserialize<ItemPostRequest>(myJsonString); but that's missing the validation.

How to use the validation / how to manually deserialize and validate JSON like Web API does it internally?

In my case the JSON string is part of form-data with keys like file and json, but the form-data formatter only cares about splitting the form-data into key-value pairs, it doesn't care about deserializing the json and the model validation for it. So I have to do this manually - but how?

stefan.at.kotlin
  • 15,347
  • 38
  • 147
  • 270
  • 1
    Does this answer your question? [How to force System.Text.Json serializer throw exception when property is missing?](https://stackoverflow.com/questions/62570159/how-to-force-system-text-json-serializer-throw-exception-when-property-is-missin) – derpirscher Jan 24 '21 at 21:13

2 Answers2

1

Deserialize the JSON in a model binder, like written here: https://stackoverflow.com/a/49471892 Then the validation will be done automatically :-)

stefan.at.kotlin
  • 15,347
  • 38
  • 147
  • 270
0

Perhaps something like below. I have not tested it, but you should be able to use TryValidateModel() to manually validate your ItemPostRequest based on your class annotations (e.g. [Required]).

// Deserialize
var itemPostRequest = JsonSerializer.Deserialize<ItemPostRequest>(myJsonString);
// Reset just in case
ModelState.Clear();
// Manually validate the model using the annotations on the model class
TryValidateModel(itemPostRequest);

// If it fails, return error
if (!ModelState.IsValid)
{
   return BadRequest(ModelState);
}

// Otherwise we're good, keep going...
Bryan Lewis
  • 5,629
  • 4
  • 39
  • 45
  • Thank you, that indeed likely works, but there's much code in the action method when doing it that way. I ended up using a model binder (see my own answer). – stefan.at.kotlin Jan 26 '21 at 19:37