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
Currently, all of our action method’s parameters are using the "string" data type. Let’s see how we can improve upon that design.
Follow Along
To follow along commiting your changes to this course, you'll need to fork the aspnet-fitness-frog repo. Then you can clone, commit, and push your changes to your fork like this:
git clone <your-fork>
cd aspnet-fitness-frog
git checkout tags/v2.4 -b working-with-non-string-data
Additional Learning
For more information about the Visual Studio Locals window, see this page on MSDN.
Currently, all of our Add action method's
parameters are using the string data type.
0:00
This is a natural fit for values that
are being submitted by the form,
0:05
because the field values are represented
in the request body as text.
0:09
If we wanted to convert the date
parameter to an actual date time value,
0:14
we could write the following code.
0:18
First, we need a DateTime variable.
0:21
Then, we can make a call to
the DateTime.TryParse static method,
0:26
passing in the date parameter and
our DateTime variable as an out parameter.
0:32
While this approach would work,
it's a lot of extra code to write.
0:38
Fortunately, MVC's model binder
will do the work for us.
0:42
All we need to do is change
our parameter data types and
0:46
the model binder will automatically
attempt to convert the incoming values
0:50
to the expected data types.
0:55
Let's update the date parameter
to be of type DateTime,
0:57
activityId to be of type int,
duration to be of type double,
1:01
intensity to be of type
Entry.IntensityLevel,
1:08
which is an enum in the Entry class that
defines the available intensity levels,
1:17
exclude to be of type bool,
and notes can remain a string.
1:27
Go ahead and remove this bit of code,
and press F5 to run our app.
1:34
This time, let's try saving the form
without providing any values.
1:42
And we get an error.
1:48
The parameters dictionary
contains a null entry for
1:50
parameter date of non nullable
type System.DateTime.
1:53
For our method Add in our controller
EntriesController, an optional parameter
1:58
must be a reference type, a nullable type,
or be declared as an optional parameter.
2:03
That is a long-winded way of telling
us that MVC was unable to call
2:09
our action method, because the request
didn't provide a value for
2:13
the date parameter, and our action
method parameter doesn't allow nulls.
2:18
To work around this issue, we need to
update each of our parameters that
2:23
are using a data type that doesn't
allow nulls to be nullable.
2:27
So date, activityId,
duration, intensity, and
2:35
exclude all need to use
the corresponding nullable types.
2:39
That's easy to do.
2:44
We just need to add a question
mark after the data type.
2:45
DateTime?
2:51
Int?
2:56
Double?
2:59
IntensityLevel?
3:03
And bool?.
3:05
Let's run our app again and
see if that fixed the issue.
3:09
Let's start by saving our form
without providing any values.
3:14
Okay, we hit our breakpoint.
3:19
We're good so far.
3:21
Press F5 to continue.
3:23
And we're back at our form.
3:26
Let's enter values and
save the form again.
3:28
1/1/2016.
3:31
1, 23, Low, False.
3:33
And this is my note.
3:39
And save the form.
3:43
If we view the Locals window, which shows
all of the currently in scope variables,
3:45
we can see that our parameters
have all of our provided values.
3:50
Press F5 to continue.
3:54
And all of our values,
with the exception of the Exclude field,
3:57
have been redisplayed back to us.
4:01
The exclude field isn't
retaining its value
4:05
because of how MVC handles
rendering element attributes.
4:08
When MVC is writing a boolean
value to an attribute,
4:12
it will omit the attribute
if the value was false or
4:15
render the attribute name equal to
the attribute name if the value was true.
4:19
We can see this in action by supplying
a value of true and saving the form again.
4:25
Now the field value that is
redisplayed back to us is value,
4:32
which is the name of the attribute
that we're trying to set.
4:37
We can work around this issue by
converting our boolean value to a string.
4:40
First, let's surround our expression
with a set of parentheses.
4:59
Then we need to check if
the ViewBag.Exclude property is null.
5:03
And if it isn't,
call the ToString method on it.
5:07
Otherwise, we'll render an empty string.
5:13
Now, if we refresh the page,
you'll see the expected behavior.
5:18
The exclude field is now set to True.
5:28
Don't worry too much about this issue and
the workaround that we're using here.
5:31
Normally, you would use a check box to
represent a boolean value in a form,
5:35
not a text box, which prevents
this issue from even surfacing.
5:40
We'll switch to using a checkbox for
the Exclude field in the next section.
5:44
Go ahead and stop the app.
5:49
If you're using GitHub,
let's commit our changes.
5:53
Enter a commit message of Updated
the EntriesController Add
6:00
method parameter data types and
click the Commit All button.
6:07
After the break, we'll take a look
at how we can use model state
6:15
to improve our handling of invalid values.
6:18
You need to sign up for Treehouse in order to download course files.
Sign up