Aller au contenu principal

19-12 Supprimer une question

Dernière étape, la suppression!

Ajout de l'action QuestionsController#Delete

Commençons par une action simple.

Snowfall.Web.Mvc/Controllers/QuestionsController.cs
// DELETE /evenements/{evenementId}/questions/{id}
[HttpDelete("{id:int}")]
[Authorize]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(int id, int evenementId)
{
return RedirectToAction("Index", "Questions", new { evenementId = evenementId});
}
info
  • HttpDelete action activée dans le cas d'une requête DELETE à /evenements/{evenementId}/questions/{id}
  • [Authorize] l'utilisateur doit être authentifié
  • [ValidateAntiForgeryToken] on valide le jeton CSRF pour s'assurer que la requête vient bien de notre application.

Ajout d'un lien supprimer sur les questions

Snowfall.Web.Mvc/Views/Questions/Index.cshtml
<!-- ... -->

@foreach (Question question in Model.Questions)
{
<div class="card mb-3">
<div class="card-body">
<p class="card-text" style="white-space: pre-line">@question.Contenu</p>
<a class="card-link small"
asp-controller="Questions"
asp-action="Edit"
asp-route-evenementId="@Model.Evenement.Id"
asp-route-id="@question.Id">Modifier</a>

<form class="card-link d-inline" asp-controller="Questions"
asp-action="Delete"
asp-route-id="@question.Id"
asp-route-evenementId="@question.EvenementId">
<input type="hidden" name="_method" value="DELETE" />
<button class="btn btn-danger btn-sm">Supprimer</button>
</form>
</div>
</div>
}

<!-- ... -->
info

asp-action vers l'action Delete du contrôleur asp-route-id le id de la question à supprimer asp-route-evenementId le id de l'événement associé, pour construire la route

De plus, remarquez qu'on ajoute un input hidden pour préciser que le formulaire doit être considéré comme une action HTTP DELETE et non POST.

Cependant, si vous testez, le bouton ne fait que rediriger vers la liste de questions puisque c'est ce que nous avons dit de faire à l'action Delete du contrôleur. Il faudra donc remédier à la situation!

Encore QuestionService et QuestionRepository! 🫣

Il faut procéder à la suppression et vous l'aurez encore deviné... une fonction de repo et service sera requise!

On doit ajouter Delete() à QuestionService et QuestionRepository.

  1. IQuestionRepository
    Snowfall.Data/Repositories/IQuestionRepository.cs
    public interface IQuestionRepository
    {
    Task<Question?> FindById(int id);
    Task<List<Question>> FindByEvenementIdAndUserId(int evenementId, string userId);
    Task<Question> Create(Question question);
    Task<bool> Update(Question question);
    Task<bool> Delete(int id);
    }
  2. IQuestionService
    Snowfall.Application/Services/IQuestionService.cs
    public interface IQuestionService
    {
    Task<Question?> FindById(int id);
    Task<List<Question>> FindByEvenementIdAndUserId(int evenementId, string userId);
    Task<Question> Create(Question question);
    Task<bool> Update(Question question);
    Task<bool> Delete(int id);
    }
  3. QuestionRepository Utilisez l'aide contextuelle en cliquant sur le nom de la classe et utilisez Implement missing members. Implémentez la fonction pour supprimer une question en fonction d'un id.
    Snowfall.Data/Repositories/QuestionRepository.cs
    public async Task<bool> Delete(int id)
    {
    string sql = @"
    DELETE FROM questions
    WHERE id = @Id
    ";

    using (IDbConnection connection = _dbContext.CreateConnection())
    {
    var affectedRows = await connection.ExecuteAsync(sql, new { Id = id});
    return affectedRows == 1;
    }
    }
  4. QuestionService Idem pour le service, utilisez l'aide contextuelle en cliquant sur le nom de la classe et utilisez Implement missing members.
    Snowfall.Application/Services/QuestionService.cs
    public async Task<bool> Delete(int id)
    {
    return await _questionRepository.Delete(id);
    }

Et finalement on Delete!

Snowfall.Web.Mvc/Controllers/QuestionsController.cs
public async Task<IActionResult> Delete(int id, int evenementId)
{
var evenement = await _evenementService.FindById(evenementId);
var question = await _questionService.FindById(id);

if (evenement == null || question == null)
return NotFound();

if (question.UtilisateurId != User.Identity?.Id())
return Forbid();

await _questionService.Delete(question.Id);

return RedirectToAction("Index", "Questions", new { evenementId = evenementId});
}

Vous pouvez essayer et devriez être en mesure de supprimer les questions que vous avez ajoutés.

C'est un peu brutal comme approche cependant puisqu'il n'y a pas de confirmation de suppression, mais nous y reviendrons!