Dissident Rage
Dissident Rage

Reputation: 2716

C# Validating JSON Input

I've got my Models all annotated up with validation rules.

I've got a controller store method set up to create a new Model.

I've got JSON being parsed from the request body, after making a copy of the stream so that it's still accessible later.

I'm just trying to actually use those annotations now without having to do a whole bunch of... this:

if (!json.ContainsKey("name")) {
    throw new Exception("Name is not set.");
}
if (!json["name"].GetType().Equals(typeof(String))) {
    throw new Exception("Name is not a string");
}

string name = ((string) json["name"]).Trim();

if (name.Length == 0) {
    throw new Exception("Name cannot be empty");
}
if (name.Length > 100) {
    throw new Exception("Name must be less than 100 characters.");
}

I can't find anything that doesn't make a bunch of mindless assumptions. This, for example, makes no sense; why would I care anything about ModelState for an object that doesn't exist yet? Why would I, for that matter, care about the state of a Model at the point of entry on an update endpoint? Shouldn't it be fixed before it's even inserted into the database?

// POST: Movies/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
    [Bind("ID,Title,ReleaseDate,Genre,Price, Rating")] Movie movie)
{
    if (ModelState.IsValid)
    {
        _context.Add(movie);
        await _context.SaveChangesAsync();
        return RedirectToAction("Index");
    }
    return View(movie);
}

I've tried Newtonsoft's JSON.NET Schema and it introduces so many hardline and contradictory requirements (on top of being paid and closed source) that it's just painful to use. Please don't recommend that.

Upvotes: 2

Views: 886

Answers (1)

Guru Stron
Guru Stron

Reputation: 143243

ModelStateDictionary (which is exposed by ControllerBase.ModelState property):

Represents the state of an attempt to bind values from an HTTP Request to an action method, which includes validation information.

So you should care about it exactly for the reasons you specified - to "use those annotations now without having to do a whole bunch of... ".

Framework will try to bind the data from incoming request to your model (i.e. Movie movie in your code), analyzing the validation annotations you've specified and will reflect the results in ModelState, i.e. if there were no errors - ModelState.IsValid returns true - otherwise it returns false with corresponding errors saved to it.

Upvotes: 5

Related Questions