2017-07-06 1 views
0

J'ai essayé de corriger la validation sur mon formulaire depuis un moment, mais je n'arrive pas à le faire fonctionner correctement. La validation fonctionne correctement, sauf si je saisis une adresse e-mail valide. Si je le fais, alors il saute toutes les autres validations pour une raison quelconque.Impossible de corriger la validation ASP.NET MVC

En outre, j'apprécierais des conseils au sujet de si je le fais bien avec la division de tout dans le contrôleur. Devrait-il y avoir 2 actions (1 pour GET pour charger simplement le formulaire vide et 1 pour POST quand l'utilisateur le soumet)? Est-ce que je fais quelque chose de mal là-bas?

EDIT: Correction: Si j'entre une adresse e-mail valide, le formulaire est correctement envoyé et ignore l'autre validation. Si je n'ai pas d'adresse email valide, la validation vérifie tout.

Voilà ma classe de modèle:

public class User 
{ 
    public int ID { get; set; } 

    [DisplayName("Name")] 
    [Required(ErrorMessage = "Name is required")] 
    public string Name { get; set; } 

    [DisplayName("Email")] 
    [DataType(DataType.EmailAddress)] 
    [Required(ErrorMessage = "Email is required")] 
    [RegularExpression(
     @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" + 
      @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", 
     ErrorMessage = "Invalid email")] 
    public string Email { get; set; } 

    [DisplayName("Password")] 
    [DataType(DataType.Password)] 
    [Required(ErrorMessage = "Password required")] 
    [MinLength(6, ErrorMessage = "Min 6 characters")] 
    public string Password { get; set; } 
} 

Voici mon contrôleur:

public ActionResult Register() 
    { 
     ViewBag.LoggedIn = false; 

     return View(); 
    } 

    [HttpPost] 
    public ActionResult Register(User user) 
    { 
     ViewBag.LoggedIn = false; 

     user.Password = PasswordHash.CreateHash(user.Password); 

     using (var context = new FoundationContext()) 
     { 
      // if user exists 
      if (context.Users.FirstOrDefault(n => n.Email == user.Email) != null) return Login(true); 

      context.Users.Add(user); 
      context.SaveChanges(); 
     } 

     return View("~/Views/Home.Index.cshtml"); 
    } 

Et voici ma forme:

@using (Html.BeginForm()) 
    { 
     @Html.AntiForgeryToken() 

     <div class="form-horizontal"> 
      @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
      <div class="form-group"> 
       @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) 
        @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) 
       </div> 
      </div> 

      <div class="form-group"> 
       @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } }) 
        @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" }) 
       </div> 
      </div> 

      <div class="form-group"> 
       @Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } }) 
        @Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" }) 
       </div> 
      </div> 

      <div class="form-group"> 
       <div class="col-md-10 text-center"> 
        <input type="submit" value="Register" class="btn btn-primary" /> 
       </div> 
      </div> 
     </div> 
    } 

Et en bas bien sûr du corps comprend:

@Scripts.Render("~/bundles/jquery") 
@Scripts.Render("~/bundles/jqueryval") 
@Scripts.Render("~/bundles/bootstrap") 
@RenderSection("scripts", required: false) 
+0

Vous ne vérifie pas si le modèle est valable dans l'action HttpPost 'ModelState.IsValid '. – Scrobi

Répondre

1

Afin de vérifier si le modèle posté est valide, vous devez vérifier ModelState.IsValid dans l'action de publication (voir dans l'exemple ci-dessous).

De même, j'apprécierais des conseils sur si je le fais bien avec la scission de tout dans le contrôleur. Devrait-il y avoir 2 actions (1 pour GET pour charger simplement le formulaire vide et 1 pour POST quand l'utilisateur le soumet)? Est-ce que je fais quelque chose de mal là-bas?

L'approche est correcte, mais ce n'est pas le cas.

En supposant que vous avez une vue Register.cshtml (pas une vue partielle): Puisqu'une vue a un modèle, vous devriez toujours le fournir.Ainsi, votre méthode get devrait ressembler à ceci:

public ActionResult Register() 
{ 
    ViewBag.LoggedIn = false; 
    var model = new User(); 
    return View(model); 
} 

Pour la méthode post il y a 2 approches:

  1. POST-REDIRECT-GET modèle (PRG) - plus complexe un peu (mais à mon avis, c'est une façon plus correcte de le faire). Post méthode au lieu de retourner une vue devrait renvoyer un résultat de redirection à la fois en cas d'erreur et en cas de succès. Pour le traitement de l'état modèle invalide, vous pouvez utiliser certaines approches qui sont décrites here

  2. Votre

    [HttpPost] 
    public ActionResult Register(User user) 
    { 
        ViewBag.LoggedIn = false; 
        if(!this.ModelState.IsValid) 
        { 
        return View(user); 
        //this will render a view with preserved invalid model state so all the values with the corresponding error messages will be shown. 
        } 
    
        user.Password = PasswordHash.CreateHash(user.Password); 
    
        using (var context = new FoundationContext()) 
        { 
         // if user exists 
         if (context.Users.FirstOrDefault(n => n.Email == user.Email) != null) return Login(true); 
    
         context.Users.Add(user); 
         context.SaveChanges(); 
        } 
    
        return RedirectToAction("Index", "Home"); 
    } 
    
2

Utilisez Modelstate.IsValid. Il vous indique si des erreurs de modèle ont été ajoutées à ModelState.

public ActionResult Register(User user) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(); 
    } 

    //your code 
} 
0

Tout d'abord, la structure semble correcte, de diviser les actions d'avoir une action publierez différenciée est correcte et une bonne façon de le faire.

Je ne suis pas en mesure de tester, mais je pense que le problème est que vous ne gérez pas la validation correctement dans votre contrôleur; vous devriez vérifier le ModelState pour être valide.

[HttpPost] 
    public ActionResult Register(User user) 
    { 
     if (ModelState.IsValid) 
     { 
      ViewBag.LoggedIn = false; 

      user.Password = PasswordHash.CreateHash(user.Password); 

      using (var context = new FoundationContext()) 
      { 
       // if user exists 
       if (context.Users.FirstOrDefault(n => n.Email == user.Email) != null) return Login(true); 

       context.Users.Add(user); 
       context.SaveChanges(); 
      } 

      return View("~/Views/Home.Index.cshtml"); 
     } 
     return View(user); 
    } 

De cette façon, s'il y a une erreur dans le modèle (en fonction des règles que vous mettez avec DataAnnotations).

Aussi je ne suis pas sûr que vos DataAnnotations Les attributs sont le correct: Certains diffèrent de ceux qui sont utilisés dans cet article:

https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation

Hope this helps.