Une gestion d’erreur de son API .Net automatique via ses exceptions
...
Dans ce court article je vais vous expliquer comment faire en sorte que votre formulaire généré avec le moteur de templating Razor ait bien le bon champ « action » et non un champ « action » vide.
En termes d’expérience, je suis assez novice en ASP .NET MVC et je pense que c’est typiquement une erreur lorsque que l’on débute avec ce framewok.
Pour un client je devais créer un écran avec un formulaire (ce qui est une demande assez classique). Le framework permet avec le moteur de templating Razor de générer certains éléments HTML. Dont l’élément HTML « form » avec les attributs adéquates.
Je construit donc ma page en HTML/Razor tranquillement puis je teste si mon formulaire me renvoie bien les données saisies. Et là, c’est pas le navigateur qui me recharge juste la page ! Aucune données est envoyées au modèle…
Voici un exemple de ce que j’avais à peu prés :
La vue – Index.html
@model AperoTech.AspNetMvc.Models.ManageUsers <div style="margin-top: 20px;"> @using (Html.BeginForm("Add", "AdminUser", FormMethod.Post)) { <label>Name</label> @Html.TextBoxFor(model => model.Name, new { id = "tb-name" }) <label>First name</label> @Html.TextBoxFor(model => model.FirstName, new { id = "tb-first-name" }) <input type="submit" value="Add" /> } </div>
Le contrôleur – AddUserController.cs
using System.Web.Mvc; using AperoTech.AspNetMvc.Models; namespace AperoTech.AspNetMvc.Controllers { [RouteArea("admin"), RoutePrefix("user"), Route("{action=id}")] public class ManageUsersController : Controller { // GET public ActionResult Index() { ManageUsers manageUsers = new ManageUsers(); return View(manageUsers); } [HttpPost] public ActionResult Add(ManageUsers manageUsers) { return View("Index", manageUsers); } } }
Le modèle (ViewModel) – AddUserViewModel.cs
namespace AperoTech.AspNetMvc.Models { public class ManageUsers { public string Name { get; set; } public string FirstName { get; set; } } }
Du coup, quand j’inspecte le code HTML dans le navigateur, je remarque que l’attribut « action » de l’élément HTML « form » n’a pas de valeur.
Après plusieurs recherches sur internet, je ne trouve pas la réponse à mon problème. J’explique du coup le bogue à un collègue et il me donne comme piste : le moteur de templating (Razor) n’arrive pas à faire la correspondance à un contrôleur.
Le problème est que Html.BeginForm fait la correspondance avec un contrôleur en se basant sur son nom de classe et non sur la route…
En effet, la correction est assez simple, il suffit de mettre le nom de la classe, ici ManageUsersController, mais sans le suffixe « Controller ». Ce qui donne :
@model AperoTech.AspNetMvc.Models.ManageUsers <div style="margin-top: 20px;"> @using (Html.BeginForm("Add", "ManageUsers", FormMethod.Post)) { <label>Name</label> @Html.TextBoxFor(model => model.Name, new { id = "tb-name" }) <label>First name</label> @Html.TextBoxFor(model => model.FirstName, new { id = "tb-first-name" }) <input type="submit" value="Add" /> } </div>
Ainsi lorsque l’on inspecte le code HTML généré, on remarque bien que l’attribut « action » de l’élément HTML « form » a la bonne valeur :
Voilà ! 🙂
J’espère que ce petit article vous a aidé si, comme moi, vous avez bloqué sur ce genre de petit bogue qui en fait dû à une mauvaise utilisation du framework.
Code disponible sur mon GitHub, la branche « master » contient le bogue et la branche « fix » contient la correction.
On va voir comment avoir en quelques minutes des assertions qui vont vérifier les endpoints de notre API avec des scénarios de ce genre: Feature: Create a new account As a visitor, I can create an account to access the game Scenario: A visitor c...
Depuis .NET 9, le le support d’OpenAPI est directement inclus dans .NET et ne passe plus par les librairies Swagger par défaut (plus d’info sur ce choix ici si jamais ça vous intéresse). De façons simplifiée, la librairie Swashbuckle.AspNetCore.Sw...
Description du problème Par défaut, il n’est pas autorisé de faire des requêtes entre une application qui est dans un domaine A vers une autre qui serait dans un domaine B (pour des raisons de sécurité, il y a plus de détails dans les sources). S...