ASP .NET MVC – Html.BeginForm : L’attribut HTML « action » n’est pas généré pour l’élément « form »

Photo by Jackson So on Unsplash

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.

Contexte

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.

Correction

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.

Written By

shareitcode

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.