Model Binding and Validation: an overview
Never trust what a form sends. Validate on the server every time, and in the browser too for quick feedback; ASP.NET Core does both from one set of rules on the model.
Apprentice · ASP.NET Core · Web Development · Updated
After this lesson you can
- Explain why input is validated on the server always, and in the browser as well
Key takeaways
- Never trust what a form sends: input can be wrong by mistake, or on purpose, in a request sent with no form at all.
- Always validate on the server, because browser checks can be skipped. Validate in the browser too, for quick feedback.
- Put the rules on the model as attributes, and ASP.NET Core checks them on the server and writes them into the form for the browser.
In Model Binding a Form, a product with an empty name came back to the form, because ASP.NET Core treats a plain string as required. Real forms need more rules: a price above zero, a name of at most 40 characters, an email that looks like an email. Checking input against rules like these is validation.
Never trust input
Anything a form sends can be wrong:
- by mistake: a typo, a field left empty, a price of
-5; - on purpose: someone sending a request straight to your app, with no form at all, to see what breaks.
Your app has to cope with both. Bad data that gets into the database stays there, and every page that shows it shows it wrong.
Two places to check
| In the browser (client side) | On the server (server side) | |
|---|---|---|
| When | Before the form is sent | When the request arrives |
| Good for | Quick feedback: the message appears as you type | Safety: it's the only check nobody can skip |
| Can be skipped? | Yes: switch off JavaScript, or send a request without the form | No |
So the rule is: always validate on the server, and also validate in the browser for a better experience. Browser checks are a courtesy to the user; server checks are the protection.
One set of rules, both places
Writing every rule twice, once in C# and once for the browser, would be a recipe for the two drifting apart. ASP.NET Core avoids it:
- You put the rules on the model, as attributes:
[Required],[StringLength(40)],[Range(0.01, 1000)]. - On the server, model binding checks them as it fills the model, and records any problem in
ModelState. - In the browser, the tag helpers write the same rules into the form as
data-valattributes, and a small validation script checks them before the form is sent.
The next two lessons show both halves.
Check yourself
1 question to try on the lesson page.
So what
Validate on the server because you must, and in the browser because it's kind. With rules on the model, one set of attributes does both.