Updating QuizController

Remember the #region RESTful conventions methods in our QuizController.cs file? It's time to update its contents to support CRUD operations on Quiz entities.

Here's the new code (new and updated lines are highlighted):

[...]

#region RESTful conventions methods
/// <summary>
/// GET: api/quiz/{id}
/// Retrieves the Quiz with the given {id}
/// </summary>
/// <param name="id">The ID of an existing Quiz</param>
/// <returns>the Quiz with the given {id}</returns>
[HttpGet("{id}")]
public IActionResult Get(int id)
{
var quiz = DbContext.Quizzes.Where(i => i.Id == id)
.FirstOrDefault();

// handle requests asking for non-existing quizzes
if (quiz == null)
{
return NotFound(new
{
Error = String.Format("Quiz ID {0} has not been found", id)
});
}

return new JsonResult(
quiz.Adapt<QuizViewModel>(),
new JsonSerializerSettings()
{
Formatting = Formatting.Indented
});
}

/// <summary>
/// Adds a new Quiz to the Database
/// </summary>
/// <param name="model">The QuizViewModel containing the data to insert</param>
[HttpPut]
public IActionResult Put([FromBody]QuizViewModel model)
{
// return a generic HTTP Status 500 (Server Error)
// if the client payload is invalid.
if (model == null) return new StatusCodeResult(500);

// handle the insert (without object-mapping)
var quiz = new Quiz();

// properties taken from the request
quiz.Title = model.Title;
quiz.Description = model.Description;
quiz.Text = model.Text;
quiz.Notes = model.Notes;

// properties set from server-side
quiz.CreatedDate = DateTime.Now;
quiz.LastModifiedDate = quiz.CreatedDate;

// Set a temporary author using the Admin user's userId
// as user login isn't supported yet: we'll change this later on.
quiz.UserId = DbContext.Users.Where(u => u.UserName == "Admin")
.FirstOrDefault().Id;

// add the new quiz
DbContext.Quizzes.Add(quiz);
// persist the changes into the Database.
DbContext.SaveChanges();

// return the newly-created Quiz to the client.
return new JsonResult(quiz.Adapt<QuizViewModel>(),
new JsonSerializerSettings()
{
Formatting = Formatting.Indented
});

}

/// <summary>
/// Edit the Quiz with the given {id}
/// </summary>
/// <param name="model">The QuizViewModel containing the data to update</param>
[HttpPost]
public IActionResult Post([FromBody]QuizViewModel model)
{
// return a generic HTTP Status 500 (Server Error)
// if the client payload is invalid.
if (model == null) return new StatusCodeResult(500);

// retrieve the quiz to edit
var quiz = DbContext.Quizzes.Where(q => q.Id ==
model.Id).FirstOrDefault();

// handle requests asking for non-existing quizzes
if (quiz == null)
{
return NotFound(new
{
Error = String.Format("Quiz ID {0} has not been found",
model.Id)

});
}

// handle the update (without object-mapping)
// by manually assigning the properties
// we want to accept from the request
quiz.Title = model.Title;

quiz.Description = model.Description;
quiz.Text = model.Text;
quiz.Notes = model.Notes;

// properties set from server-side
quiz.LastModifiedDate = quiz.CreatedDate;


// persist the changes into the Database.
DbContext.SaveChanges();

// return the updated Quiz to the client.
return new JsonResult(quiz.Adapt<QuizViewModel>(),
new JsonSerializerSettings()
{
Formatting = Formatting.Indented
});

}

/// <summary>
/// Deletes the Quiz with the given {id} from the Database
/// </summary>
/// <param name="id">The ID of an existing Test</param>
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
// retrieve the quiz from the Database
var quiz = DbContext.Quizzes.Where(i => i.Id == id)

.FirstOrDefault();

// handle requests asking for non-existing quizzes
if (quiz == null)
{
return NotFound(new
{
Error = String.Format("Quiz ID {0} has not been found", id)
});
}

// remove the quiz from the DbContext.
DbContext.Quizzes.Remove(quiz);
// persist the changes into the Database.
DbContext.SaveChanges();

// return an HTTP Status 200 (OK).
return new OkResult();
}
#endregion

[...]
It goes without saying--yet we're still saying it--that these changes require the using TestMakerFree.Data reference at the beginning of the file.

The preceding source code contains some comments that will help explain the implementation details of what we just did. Nonetheless, it will be useful to focus on the following highlights:

  • We updated our already-implemented Get method so that it will be able to handle requests pointing to non-existing items. Although this is not strictly related to what we're doing now, we took the chance to do that while we were there.
  • We implemented the Put, Post, and Delete methods to make them actually perform the expected server-side operations to add, update, and delete a quiz instead of throwing a NotImplementedException, like they were doing since Chapter 2, Backend with .NET Core.
  • We added the [FromBody] parameter attribute to the Put and Post methods signatures; we did this to tell .NET Core to fetch the QuizViewModel sent by our Angular app--in JSON format--from the request body.
  • We used the Adapt<TDestination>() feature from the Mapster ORM library at the end of the Put and Post methods to return a new QuizViewModel to the client built upon the created/modified Quiz.

Also, note how we didn't use Mapster to populate the Quiz entity from the QuizViewModel in the Post method, as we have chosen to manually treat, check, and assign each property separately there; we did that to gain more control over these changes, separating the properties that the user is allowed to modify from those who should be set from server-side only.

We should also spend a few moments talking about what we didn't do here: no error-handling strategies, no validation or integrity checks on user-input values, no authentication, just to name a few. This isn't a robust, production-ready code yet, and we need to be fully aware of that. There's nothing wrong with it; we're still in the development phase, after all, and we'll refine these aspects once we get a good grip on all the features we still need to know.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.247.181