2

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.

5
  • 2
    "Why would I, for that matter, care about the state of a Model at the point of entry on an update endpoint"...because that's the point at which you want to validate that the user sent something usable. Why carry on with any processing if that data is un-usable? The model binder will map the JSON properties into the model type you've specified (Movie in this case). Then it's up to you to decide whether what's been sent is considered valid or not. Annotations can help you do this (although it's possible to write code to implement more complex rules too, and/or create custom annotations). Commented Sep 16, 2020 at 15:10
  • 1
    "why would I care anything about ModelState for an object that doesn't exist yet? " ... the object does exist - it's a Movie object and you can validate it before attempting to insert it into your database. The ModelState tells you whether the incoming object passed all the validation rules you set for it, or not. I'm not really sure I understand what your beef is. Commented Sep 16, 2020 at 15:11
  • Are you saying before executing the method code, the framework has tried to map data from the input into a new model instance, and that's what's being passed into the method? Commented Sep 16, 2020 at 15:15
  • 3
    That's exactly what's happening, yes. it saves you the trouble of parsing the input data yourself, and also allows this up-front validation to occur, so you can easily discard junk data before even starting to process the request. I wonder if you've simply misunderstood what the process is, leading to your confusion? Commented Sep 16, 2020 at 15:20
  • I read back through the docs again and it wasn't clarified that this is what it's doing. Thanks! Commented Sep 16, 2020 at 15:21

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

3 Comments

The only examples I'm ever seeing of that are just on models that already exist, and often on a read-only operation (index, get, etc.), so I have been operating under the assumption that it doesn't actually do what I'm looking for.
@DissidentRage can you please add a link to the example where ModelState is used for read-only operation?
The documentation was not clear. ADyson in the comments above clarified what it's doing before executing the method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.