This course will be retired on June 1, 2025.
Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Start a free Courses trial
to watch this video
How that we've updated our API to use our DTO, let's test our changes!
Implementing Custom Validation for the Duration Field
At the end of the video, we tested that we were able to create a new entry resource. We noticed though, that we could provide a value of "0" for the duration
property.
It doesn't really make sense for an activity to have a duration of "0", so we probably should require users to provide a value greater than "0". To resolve this issue, let's see how we can leverage custom validations.
Adding custom validations is actually pretty easy to do. We simply write code to validate the entry DTO and use the ModelState AddModelError
method to add any errors that we detect.
Here are the steps for implementing our custom validation:
- Add a private method to the API controller class
- We only want our validation to run if there aren't any other errors for the
Duration
field - Check if the
Duration
property has a value less than or equal to "0" - If so, then add a model error for the
entry.Duration
field- In Postman we noticed that Web API was prefixing our field names with the parameter name, so let's keep things consistent when adding our model error
- Add our error message
And here's the code:
private void ValidateEntry(EntryDto entry)
{
// If there aren't any "Duration" field validation errors
// then make sure that the duration is greater than "0".
if (ModelState.IsValidField("Duration") && entry.Duration <= 0)
{
ModelState.AddModelError("entry.Duration",
"The Duration field value must be greater than '0'.");
}
}
Then, we just need to call the ValidateEntry
method from the Post
and Put
methods, right before the model state is checked.
public IHttpActionResult Post(EntryDto entry)
{
ValidateEntry(entry);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var entryModel = entry.ToModel();
_entriesRepository.Add(entryModel);
entry.Id = entryModel.Id;
return Created(
Url.Link("DefaultApi", new { controller = "Entries", id = entry.Id }),
entry);
}
public IHttpActionResult Put(int id, EntryDto entry)
{
ValidateEntry(entry);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_entriesRepository.Update(entry.ToModel());
return StatusCode(System.Net.HttpStatusCode.NoContent);
}
Now let's retest! Press F5 to start debugging and switch to Postman.
{
"date": "2/1/2017",
"activityId": 1,
"duration": 0,
"intensity": 2
}
And now we get the error message from our custom validation!
Automapper
Automapper can help ease the overhead of leveraging DTOs by eliminating the code to map values from your models to your DTOs and vice versa.
Here's code that initializes Automapper to map two typesβFoo and Barβto their respective DTOs:
Mapper.Initialize(cfg => {
cfg.CreateMap<Foo, FooDto>();
cfg.CreateMap<Bar, BarDto>();
});
Then in your application code, you can execute the mappings like this:
var fooDto = Mapper.Map<FooDto>(foo);
var barDto = Mapper.Map<BarDto>(bar);
For more information on Automapper, see their website at automapper.org.
Finished Project Code
Here's how to get the code for the finished project:
git clone git@github.com:treehouse-projects/aspnet-fitness-frog-spa.git
cd aspnet-fitness-frog-spa
Project Ideas
Need an idea for an additional project? How about creating an API for the Comic Book Library Manager web app project?
Here's how to get the code for the finished Comic Book Library Manager web app:
git clone git@github.com:treehouse-projects/dotnet-comic-book-library-manager.git
cd dotnet-comic-book-library-manager
Treehouse Community
If you ever have a question about Web API or get stuck on something, check out the Treehouse Community. Youβll find there other students and a great team of moderators who can help.
Additional Learning
- Calling an API Using JavaScript
- Error Handling
- Versioning
- Throttling
- Security
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up