2009-06-04 8 views
5

J'ai fusionné la vue de création de compte et la vue de connexion dans la même vue. Donc, c'est une vue avec deux formes, mais elles se mélangent quand je soumets. Si j'essaie de me connecter et qu'il y a une erreur qui s'affiche avec:Séparation de deux formulaires dans la même vue dans ASP.Net MVC

Html.ValidationSummary() 

les deux formes obtiennent l'erreur. Et j'ai commencé à renommer les champs en loginPassword, createPassword, parce que sinon, quand je soumets et que le mot de passe est manquant, il est marqué comme manquant des deux côtés.

Quel serait le moyen de séparer ces deux formes afin qu'elles puissent travailler de façon indépendante sur la même vue/page?

Répondre

3

je devais traiter avec le même prob lem. J'ai trouvé qu'il n'y a aucun moyen de séparer les messages de validation en utilisant le construit dans ValidationSummary(). Voici deux suggestions:

  1. Position du sommaire de validation dans une zone où il pourrait appliquer aux deux formes. Par exemple, si les formulaires de connexion et d'inscription sont côte à côte, positionnez le résumé de validation dans un div centré au-dessus des deux formulaires. J'ai trouvé un exemple de ce style sur le Mahalo login page.
  2. Dans les méthodes d'action de contrôleur appropriées, ajoutez quelque chose à ViewData indiquant quelle action a été appelée. Dans la vue, il y aura un ValidationSummary pour chaque formulaire, mais chacun sera rendu conditionnellement en fonction de ce que vous avez ajouté à ViewData.

Dans les deux cas, les champs de formulaire doivent être nommés de manière unique. Je suis allé avec la solution # 1 parce que j'étais satisfait de la façon dont je pouvais l'obtenir. Mais si vous souhaitez que le résumé de validation apparaisse dans deux emplacements différents en fonction du formulaire soumis, passez à # 2.

0

Si les formulaires postent des actions complètement différentes, votre ModelStateDictionary ne doit contenir que les erreurs fournies par l'action invoquée.

Pouvez-vous poster le code pertinent?

+0

Mais Html.ValidationSummary() sélectionne toutes les erreurs, quelle que soit la forme. – Pablo

+0

Concernant le code, vous pouvez simplement regarder la connexion et créer des actions de compte d'un projet fraîchement créé. Maintenant j'ai une méthode logInOrCreateAccount() qui montre une vue avec deux formes, une pointant vers logIn() et l'autre vers createAccount(). – Pablo

+0

Oh je vois. Oui, le résumé de validation n'est pas spécifique au formulaire. Vous pouvez placer ceci dans un emplacement central en haut de la page ou simplement l'omettre complètement. Il ne serait pas difficile d'écrire le vôtre qui prend un préfixe non plus. –

0

Je ne suis pas sûr s'il existe un moyen de diviser le ValidationSummary().

Pour vos formulaires, vous pouvez créer des classes de modèle avec lesquelles vous souhaitez vous lier, avec les différents champs. Cependant, cela ne vous rapportera pas grand chose de ce que vous avez déjà.

+0

Je suis d'accord avec le changement de nom, c'est propre mais tout va bien. C'est le ValidationSummary que je ne peux pas contourner maintenant. – Pablo

2

Les éléments d'entrée ont besoin de noms/identifiants différents même s'ils sont sous des formes différentes. Sauf s'ils ont des noms différents, il déclenchera la logique de validation pour chaque contrôle, car il correspond en fonction du nom du contrôle. Je pense que vous êtes sur la bonne voie en changeant les noms pour les différencier.

je mis en place un modèle composé, peut-être pour que vous puissiez faire quelque chose comme (note c'est incomplète):

<%= Html.TextBox("Login.Name") %> 
<%= Html.TextBox("Login.Password") %> 


<%= Html.TextBox("NewAccount.Name") %> 
<%= Html.TextBox("NewAccount.Password") %> 
<%= Html.TextBox("NewAccount.ConfirmPassword") %> 

Du côté du serveur, utilisez l'option préfixe pour le liant

public ActionResult Login([Bind(Prefix="Login")]AccountModel model) 
{ 
    ... 
} 

Et votre modèle ressemblerait à ceci:

public class AccountModel 
{ 
     public string Name { get; set; } 
     public string Password { get; set; } 
     public string ConfirmPassword { get; set; } 
} 

public class EntryPageModel 
{ 
    public AccountModel Login { get; set; } 
    public AccountModel NewAccount { get; set; } 
} 
+0

Oh! Droite. Je vais laisser les identifiants et les noms différents, cependant, ValidationSummary attrape tous les deux dans les deux formes. – Pablo

+0

J'ai mis à jour avec quelques idées sur la façon de le faire. – tvanfosson

+0

... et je pense que vous avez seulement besoin d'un résumé de validation par page. Je pense qu'il est destiné à être un résumé de toutes les erreurs dans le dictionnaire d'états du modèle. – tvanfosson

5

Ah oui, j'ai dû faire exactement cela avant.La façon dont j'ai trouvé était de mettre un drapeau dans le ViewData détaillant le formulaire qui a été posté et ensuite j'ai créé ma propre méthode d'extension pour ValidationSummary.

Le code n'est pas avec moi en ce moment, donc je vais faire de mon mieux pour faire du code aérien maintenant, c'est évidemment juste un concept de la façon de le faire, donc prenez-le à sa valeur nominale. Pour commencer, j'utiliserais la même configuration que celle proposée par tvanfosson avec son 'EntryPageModel'.

Voir - note Html.MyValidationSummary

<% using(Html.BeginForm("NewAccount", "Account")) %> 
<% { %> 
    <%= Html.MyValidationSummary("NewAccountForm") %> 

    <%= Html.TextBox("NewAccount.FirstName") %> 
    <%= Html.TextBox("NewAccount.LastName") %> 
    <%= Html.TextBox("NewAccount.Email") %> 
    <%= Html.Password("NewAccount.Password") %> 
    <%= Html.Password("NewAccount.ConfirmPassword") %> 
<% } %> 

<% using(Html.BeginForm("Login", "Account")) %> 
<% { %> 
    <%= Html.MyValidationSummary("LoginForm") %> 

    <%= Html.TextBox("Login.Email") %> 
    <%= Html.Password("Login.Password") %> 
<% } %> 

Controller - note ViewData [ "PostedForm"]

public class Account : Controller 
{ 
    private EntryPageModel _viewModel; 

    public ActionResult NewAccount(FormCollection formValues) 
    { 
     try 
     { 
      //binding and validation for _viewModel.NewAccount 
     } 
     catch 
     { 
      ViewData["PostedForm"] = "NewAccountForm"; 
      return View("RegisterAndLogin", _viewModel); 
     } 
    } 

    public ActionResult Login(FormCollection formValues) 
    { 
     try 
     { 
      //binding and validation for _viewModel.Login 
     } 
     catch 
     { 
      ViewData["PostedForm"] = "LoginForm"; 
      return View("RegisterAndLogin", _viewModel); //You'll want to pass in a model 
     } 
    } 
} 

personnalisée extension html

namespace System.Web.Mvc 
{ 
    public static class HtmlExtensions 
    { 
     public static string MyValidationSummary(this HtmlHelper html, string formName) 
     { 
      if (!string.IsNullOrEmpty(html.ViewData["PostedForm"]) 
       && (html.ViewData["PostedForm"] == formName)) 
      { 
       return html.ValidationSummary(); 
      } 

      return ""; 
     } 
    } 
} 

HTHS, Charles

+0

C'est ce qui aurait dû être falsifié dans le ValidationSummary() ... s'il y avait juste une méthode pour détecter dans quel View, appelant ainsi l'action, que ValidationSummary() ait été appelée alors cela pourrait fonctionner sans argument d'action explicite! –

+0

Bien que cela ne fonctionne pas pour la validation côté client, non? – Julian

Questions connexes