Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Web API gives us a way to check if our model state is in a valid state, and if it's not in a valid state, we can return an appropriate error response to the client, letting them know how to correct the problem.
Follow Along
To follow along committing your changes to this course, you'll need to fork the aspnet-fitness-frog-spa repo. Then you can clone, commit, and push your changes to your fork like this:
git clone <your-fork>
cd aspnet-fitness-frog-spa
git checkout tags/v3.6 -b adding-validation
The Fitness Frog client app
already includes some validation.
0:00
For example, it won't allow the user
to submit the add entry form
0:04
until they've supplied
all the required values.
0:07
Notice that the Save button is
disabled and can't be clicked.
0:10
If we supply all the required values, The
client app will enable the Save button.
0:15
Having client-side validation
doesn't mean that we can
0:24
skip implementing server-side validation.
0:27
In fact, if you had to choose between
implementing client-side and service-side
0:30
validations, it's always best to
implement your validations on the server.
0:34
Client-side validations are just
too easy for users to circumvent.
0:39
Currently, the post method just
accepts an entry object and
0:56
adds it to the database by calling
the entries repositories add method.
0:59
We're just assuming that the provided
entry object is in a valid state.
1:05
Meaning, that each of its properties
that should have a value has a value.
1:09
And that all property values meet
our expectation as to what valid
1:13
values should be.
1:18
Luckily, we don't have to assume anything.
1:20
Web API gives us a way to check if
our model state is in a valid state.
1:23
And if it's not in a valid state,
we can return an appropriate
1:27
error response to the client, letting
them know how to correct a problem.
1:31
If you've worked with
the ASP.NET MVC Framework before,
1:35
you'll feel right at home with how
Web API implements model validation.
1:38
The API controller-based class provides
a model state property that we can
1:43
use to check if the model state
is in a valid state or not.
1:47
Here at the top of our action method,
let's add an if statement.
1:53
If not |ModelState.IsValid.
1:56
And if the model state is in an invalid
state, we can call the bad request method,
2:05
which will return a response with
a 400 bad request HTTP status code.
2:10
The bad request method also provides
an overload that allows us to pass in
2:16
the model state property.
2:20
Doing this will cause the error messages
in the model state dictionary object to be
2:25
serialized to the response message body.
2:29
That will give the client the information
that they'll need to correct any
2:32
issues with the data, before they
try sending in another request.
2:35
Set a breakpoint just inside of the Post
method, and press F5 to start debugging,
2:40
so we can test our method
using Post method.
2:44
Let's start with posting an object with
no values to the entry's endpoint.
2:56
I already have a post request
here in my history, so
3:01
I'll click on it to load up the request.
3:03
Let's remove the exclude in notes
properties as they're not required.
3:10
Then, let's set date, activityId,
3:15
duration and intensity to null.
3:20
Then click the Send button.
3:29
Here we are at our breakpoint.
3:33
Let's press F10 to step through our code.
3:35
If we hover over the ModelState.IsValid
property, we can see that it was false.
3:40
So our if statement evaluated to true.
3:44
That means that we're going to return
a call to the bad request method,
3:47
passing in our model state.
3:51
Press F5 to continue execution.
3:54
Scroll down to see the response body.
3:58
So the request wasn't successful.
4:02
We can see that we received back
a 400 bad request HTTP status code.
4:05
But the error messages that we received,
telling us that the provided values
4:10
couldn't be converted to the expected
types, aren't very user friendly.
4:15
Now, let's try sending an empty object.
4:20
Just remove all of the properties and
send a set of curly braces.
4:26
Click the Send button.
4:32
Here we are at our breakpoint again,
just inside of the post action method.
4:35
Press F10 to step through our code,
and look at that.
4:39
The ModelState.IsValid property is true.
4:44
How is that possible when we
didn't supply any values?
4:48
Hover over the Entry parameter and
expand it so
4:52
that you can see the Entry
object's property values.
4:54
All of our required properties are defined
in the Entry class as non-nullable types.
4:58
During a parameter binding process,
non-nullable
5:03
types will be set to their default values
if there isn't a value to bind to.
5:06
For example the date property,
which is of type daytime will
5:10
be set to the static
value daytime.meanvalue.
5:14
ActivityId which is of
type int will be set to 0.
5:18
Duration which is of type decimal,
will also be set 0.
5:22
And intensity,
which is of type intensity level.
5:27
An enumeration defined in entry
class will also be set to 0.
5:30
If we continue execution,
we'll encounter an exception.
5:35
This is happening because the date
properties daytime minimum value can't be
5:43
persisted to the database's
daytime data column type.
5:47
Not providing all of an objects available
properties is called under-posting.
5:54
As you can from this example,
5:59
Web API by default, doesn't prevent
a client from under-posting.
6:01
We need a strategy for preventing
under-posting for breaking our validation.
6:06
You need to sign up for Treehouse in order to download course files.
Sign up