19-12 Supprimer une question
Dernière étape, la suppression!
Ajout de l'action QuestionsController#Delete
Commençons par une action simple.
// 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});
}
HttpDelete
action activée dans le cas d'une requêteDELETE
à/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
<!-- ... -->
@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>
}
<!-- ... -->
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
.
IQuestionRepository
Snowfall.Data/Repositories/IQuestionRepository.cspublic 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);
}IQuestionService
Snowfall.Application/Services/IQuestionService.cspublic 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);
}QuestionRepository
Utilisez l'aide contextuelle en cliquant sur le nom de la classe et utilisezImplement missing members
. Implémentez la fonction pour supprimer une question en fonction d'unid
.Snowfall.Data/Repositories/QuestionRepository.cspublic 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;
}
}QuestionService
Idem pour le service, utilisez l'aide contextuelle en cliquant sur le nom de la classe et utilisezImplement missing members
.Snowfall.Application/Services/QuestionService.cspublic async Task<bool> Delete(int id)
{
return await _questionRepository.Delete(id);
}
Et finalement on Delete!
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!