web-dev-qa-db-fra.com

ASP.NET MVC Login ReturnUrl toujours NULL?

À l'aide de l'authentification par formulaire dans ASP.NET MVC lorsque vous essayez de vous reconnecter à un site, il place un paramètre ReturnUrl dans la chaîne de requête. Ma méthode d'action de connexion accepte une chaîne "returnUrl". Cependant, il semble que la chaîne returnUrl soit toujours nulle, même lorsqu'elle se trouve clairement dans la chaîne de requête. Avez-vous des raisons de penser que cela pourrait être le cas ou une solution possible?

56
aherrick

Peut-être que vous n'incluez pas le paramètre ReturnURL dans l'attribut action de votre formulaire de connexion, publiant ainsi sur une URL sans ce paramètre?

24
Çağdaş Tekin

Cela a tendance à se produire lorsque vous utilisez un formulaire de connexion générique, mais vous spécifiez explicitement le Controller et ActionMethod (ce qui provoque une publication de formulaire, mais perd la chaîne de requête)

Juste pour clarifier, voici à quoi devrait ressembler votre code dans votre BeginForm:

Html.BeginForm("LogOn", "Account", new { ReturnUrl = Request.QueryString["ReturnUrl"] })

MODIFIER : Ceci est voulu par la conception même que RickAnd mentionne dans les commentaires ci-dessous. Cependant, cela ne permet pas au modèle d'interface utilisateur d'être profondément dans un site, de cliquer sur LogOn, puis de revenir à la page sur laquelle vous étiez précédemment, s'il autorise les utilisateurs anonymes. C'est un modèle couramment demandé. L'approche de David Allen à LogOff fonctionnerait également bien pour une redirection propre à LogOn.

120
davewasthere

Fondamentalement, The Asp.net MVC a des fonctionnalités cachées. Par exemple, lorsque vous transmettez la variable 'id' à l'action du contrôleur, il interprète 'id' comme identifiant par défaut et le place sur la requête du navigateur avec barre oblique.En utilisant un autre nom au lieu de 'id', nous verrons '?' plutôt que la barre oblique. En raison de la définition du nom 'id' sur la méthode RegisterRoutes dans le fichier global.asax .

Dans ce problème, vous avez créé un passeur de données personnalisé vers le contrôleur à l'aide de ce code:

using(Html.BeginForm("LogOn", "Account", FormMethod.Post))
{
//form fields
}

Ainsi, Asp.net MVC ignore les autres données utiles à transmettre à l'action du contrôleur, et nous verrons returnUrl toujours null.

Alors qu'en utilisant ceci, Asp.net MVC agit correctement et returnUrl est monté:

using(Html.BeginForm())
{
//form fields in LogOn View
}

Par ailleurs, lorsque nous utilisons un passeur de données personnalisé pour l'action du contrôleur, nous devons transmettre une autre donnée manuellement comme ceci:

using(Html.BeginForm("LogOn", "Account", new {ReturnUrl = Request.QueryString["ReturnUrl"] }))
{
//form fields
}
7

Il y a deux façons de penser aux scénarios d'ouverture et de fermeture de session. Dave Beer a décrit une façon, ci-dessus. Il existe une autre approche qui fonctionne dans de nombreuses situations. Je l'ai utilisé lorsque j'ai codé le didacticiel NerdDinner. Le didacticiel nous fournit une fonction de déconnexion qui vous déconnecte et vous ramène à la maison. Je ne voulais pas ça. Je voulais revenir à la page sur laquelle j'étais avant de me déconnecter. J'ai donc modifié mon action de déconnexion du contrôleur de compte pour qu'elle ressemble à ceci

   public ActionResult LogOff()
    {
        FormsService.SignOut();
        return Redirect(Request.UrlReferrer.ToString());
    }

Vous pouvez devenir plus amateur et passer une returnUrl et le tester, au cas où vous voudriez remplacer ce comportement. Mais je n'en ai pas besoin. Cela permet d'atteindre le résultat souhaité. La connexion peut fonctionner de la même manière. Peut-être qu'il existe des moyens d'utiliser le framework MVC pour le faire pour moi, mais jusqu'à ce que je les apprenne, c'est TRÈS simple et fonctionne de manière fiable.

3
David Allen

Essayez ce qui suit:

        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string id)
    {
        string formAction = htmlHelper.ViewContext.HttpContext.Request.RawUrl;

        TagBuilder tagBuilder = new TagBuilder("form");

        tagBuilder.MergeAttribute("id", id);
        tagBuilder.MergeAttribute("action", formAction);
        tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(FormMethod.Post), true);

        HttpResponseBase httpResponse = htmlHelper.ViewContext.HttpContext.Response;
        httpResponse.Write(tagBuilder.ToString(TagRenderMode.StartTag));

        return new MvcForm(htmlHelper.ViewContext.HttpContext.Response);
    }

Assurez-vous d'abord que vous avez défini l'URL de connexion dans le web.config, Ensuite, assurez-vous que votre formulaire de connexion ne contient rien comme une action, par exemple:

Vue:

Si vous spécifiez une action, vous obtiendrez toujours null pour l'URL de retour:

Manette:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SignIn(string userName, string password, bool? rememberMe, string returnUrl)
{
}
1