10
votes

ASP.NET MVC - Comment gérer le modèle de modèle à partir d'un autre contrôleur?

J'ai une interprétation accueillante avec une action d'index indiquant la vue Index.aspx. Il possède une section de connexion nom d'utilisateur / mot de passe. Lorsque l'utilisateur clique sur le bouton Soumettre, il publie une action de connexion dans la comptyController.

    [HttpPost]
    public ActionResult Login(LoginViewModel Model, string ReturnUrl)
    {
        User user = MembershipService.ValidateUser(Model.UserName, Model.Password);
        if (user != null)
        {
            //Detail removed here
            FormsService.SignIn(user.ToString(), Model.RememberMe);
            return Redirect(ReturnUrl);
        }
        else
        {
            ModelState.AddModelError("", "The user name or password provided is incorrect.");
        }
        // If we got this far, something failed, redisplay form
        return RedirectToAction("Index", "Home");  // <-- Here is the problem.  ModelState is lost.
    }


0 commentaires

5 Réponses :


2
votes

trois options
  1. Vous pouvez appeler l'action directement, mais le côté client n'aura pas changé son URL. Donc, au lieu d'appeler redirectToaction code>, vous pouvez appeler l'index index () code> de la classe HOMECONTROLLER CODE> Classe directement. P>

    return View("~/Views/Home/Index.aspx", data);
    


4 commentaires

N'est-ce pas la surcharge de la vue (string, chaîne, objet) pour le nom de la vue, le nom de la page maître et le modèle ne pas voir le nom, le nom du contrôleur et le modèle?


Tu as raison. Laisse-moi ajuster ma réponse. Mais je n'ai pas vérifié si cela fonctionne ou non. Faites-le et fournissez des commentaires quand cela ne fonctionne pas encore.


Je l'ai essayé. David avait raison. Votre réponse révisée fonctionne également, mais ne maintient pas d'état à moins que vous ajoutez un modèle après le nom de la vue, car certains des autres ont suggéré. +1 pour la meilleure suggestion utilisée par les gros joueurs, BTW. Excellente suggestion.


La différence entre cela et quels "grands joueurs" font, c'est ce qui précède ne changera pas l'URL car ce n'est pas une redirection. Ainsi, le formulaire soumet du navigateur après avoir corrigé les erreurs peut potentiellement aller à la mauvaise action.



2
votes

Eh bien, vous pouvez toujours faire cela

return View("~/Views/Home/Index.aspx", myModel);


2 commentaires

Comme cela est appelé à partir de l'action de connexion du contrôleur de compte, cela renvoie la vue Index dans le dossier Vues / Compte et non la vue Index du dossier Vues / Accueil


Vous avez raison, n'a pas pensé à cela. Cependant, c'est facilement résolu. THX



-1
votes

Essayez d'utiliser

return View("Index", "Home", Model)


1 commentaires

"Accueil" serait le nom de la page maître ici, pas le contrôleur.



7
votes

Comme d'autres ont dit qu'il est courant de renvoyer la vue si la validation échoue, mais que vous appelez à partir de votre contrôleur de compte, vous souhaitez spécifier le chemin complet de votre vue xxx

Il est également courant d'avoir une page de connexion séparée et de rediriger vers cette page si le login échoue. Les deux pages se soumettront à la même action de connexion. Facebook fait ceci par exemple.

ou

Comme vous souhaitez uniquement afficher un message d'erreur xxx

puis dans votre action d'index Lire le paramètre loginatemps et choisissez d'afficher le message d'erreur en conséquence.


1 commentaires

Votre option 1 était la plus facile à mettre en œuvre et accomplie exactement ce dont j'avais besoin. Merci.



7
votes

Utilisez tempdata pour enregistrer l'état entre les demandes. Utilisez des attributs spéciaux pour plus de commodité, comme indiqué ici .

quelques instants à mentionner:

  • Ne reviennent pas Vue directement de votre post-action, respect post-redirect-get motif.
  • n'utilise pas tempdata . C'est seul supposé enregistrer l'état modèle juste avant de rediriger et de le récupérer juste après avoir été redirigé.

5 commentaires

Post-redirect-get n'est crucial que lorsque l'opération réussit. Quand il échoue, il est courant de ne pas faire le motif PRG. La demande rafraîchissante ne nuit pas au système de manière ou forme de la forme ... Dans ce cas particulier, il échoue.


Eh bien, Robert, peut-être que c'est une question de goût personnel, mais je préfère PRG pour chaque fois que vous avez une chance de voir une fenêtre modale de navigateur vous demandant de republier. Je préfère plus lisse et "amitié" d'histoire "ux. Peut-être que "login" est un cas quelque peu spécial, mais dans des formes régulières, je préfère également uniquement montrer le formulaire sur cette page avec URL se terminant par "Modifier" non "Mettre à jour" (oui, je n'utilise pas le même nom d'action pour les deux).


Comment préservez-vous des erreurs d'état modèle pour l'utilisateur, si vous faites du PRG en cas de défaillance?


@ user6130, si je comprends votre question correctement, c'est exactement le point où tempdata entre en jeu. Je sauvegarde la modélisation invalide là-bas avant de rediriger pour obtenir une méthode et d'appliquer le modèle de modélisation dans cette méthode après rediriger (donc je montre facilement les erreurs à l'utilisateur sur le formulaire initial avec toutes les données saisies par l'utilisateur). C'est exaclty que Tempdata pour. J'utilise des attributs pour cela, donc je n'ai pas à polluer mes actions de contrôleur avec ces chèques de modélisation répétés fastidieux. Vous pouvez même mettre en œuvre votre propre itemPDataProvider si vous avez des exigences de déploiement spécifiques. Logique?


@Vasilio J'ai vu ce modèle et toutes les chèques TempData deviennent Messier que les chèques de modèles de modèle IMO, car au moins modélistate dispose d'une certaine structure à celle-ci et non seulement un objet typiquement dactylographié dans Tempdata. Aussi, vous pouvez obtenir des bugs occasionnels si Tempdata n'a pas été consommé si la redirection a échoué en raison de la Fluke réseau, et l'utilisateur tente de rafraîchir la page ou d'appuyer sur entrer dans la barre d'URL pour obtenir un formulaire vide, mais à la place, votre code voit Quelques tempdata [clé]! = null et leur donne une forme avec des données et des messages d'erreur sur une défaillance, quand ils n'essaient même pas de soumettre ce formulaire.