Working with Non-String Data6:21 with James Churchill
Currently, all of our action method’s parameters are using the "string" data type. Let’s see how we can improve upon that design.
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
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