2012-03-04 5 views
25

Je lien sur mon point de vue de rasoir comme ceci:redirect retourner url après la connexion

<a href="Home/Login?ReturnUrl=Disputes/Index"> disputes</a> 

dans ma méthode d'action de connexion, j'utilise ceci:

public ActionResult Login(string returnUrl) { 
      if (string.IsNullOrEmpty(returnUrl) && Request.UrlReferrer != null) 
       returnUrl = Server.UrlEncode(Request.UrlReferrer.PathAndQuery); 

     if (Url.IsLocalUrl(returnUrl) && !string.IsNullOrEmpty(returnUrl)) 
     { 
      ViewBag.ReturnURL = returnUrl; 
     } 

     return View(); 
    } 

Vu que je me sers de ce :

@Html.Hidden("returnUrl",@Request.QueryString) 

alors en mode d'action de publication:

public ActionResult LogOn(LogOnModel model, string returnUrl) 
     { 
      if (ModelState.IsValid) 
      { 
       if (membershipService.ValidateUser(model.UserName, model.Password, model.Type)) 
       { 
        formsAuthenticationService.SignIn(model.UserName, model.RememberMe); 
        SetUserInfo(model.UserName); 

       string decodedUrl = ""; 
       if (!string.IsNullOrEmpty(returnUrl)) 
        decodedUrl = Server.UrlDecode(returnUrl); 

       if (Url.IsLocalUrl(decodedUrl))      
        return Redirect(decodedUrl); 
        else 
return Redirect("Home", Index); 

} 
} 
} 

il redirige vers: /Disputes/Index mais il devrait aller à myApp/Disputes/Index où l'URL avec la chaîne de requête est comme ceci. /myApp/Home/Login?ReturnUrl=/Disputes/Index

Comment puis-je résoudre ce problème?

+0

essayez d'utiliser disputes (avec le "/") ou essayez même pas de chaîne de requête pour tester la méthode UrlReferrer. – Oliver

+0

@Oliver: J'ai essayé sans querystring et cela n'a pas fonctionné ... – DotnetSparrow

Répondre

39

J'utilise une combinaison de la suggestion ci-dessus et Request.UrlReferrer pour obtenir l'emplacement précédent:

public ActionResult LogOn(string returnUrl) 
    { 
     //So that the user can be referred back to where they were when they click logon 
     if (string.IsNullOrEmpty(returnUrl) && Request.UrlReferrer != null) 
      returnUrl = Server.UrlEncode(Request.UrlReferrer.PathAndQuery); 

     if (Url.IsLocalUrl(returnUrl) && !string.IsNullOrEmpty(returnUrl)) 
     { 
      ViewBag.ReturnURL = returnUrl; 
     } 
     return View(); 
    } 

De cette façon, je n'ai pas de mettre l'emplacement dans le ActionLink.

Je remplis un champ caché dans la page de connexion en utilisant le ViewBag.ReturnURL. Puis, dans la Connexion HttpPost ActionResult rediriger l'utilisateur vers l'emplacement dans le champ caché (si elle existe):

[HttpPost] 
    public ActionResult LogOn(LogOnModel model, string returnUrl) 
    { 
     //returnURL needs to be decoded 
     string decodedUrl = ""; 
     if (!string.IsNullOrEmpty(returnUrl)) 
      decodedUrl = Server.UrlDecode(returnUrl); 

     //Login logic... 

     if (Url.IsLocalUrl(decodedUrl)) 
     { 
      return Redirect(decodedUrl); 
     } 
     else 
     { 
      return RedirectToAction("Index", "Home"); 
     } 
    } 
+0

J'ai utilisé un champ caché dans la connexion page et maintenant je peux voir la valeur de retour dans la méthode d'action de connexion comme ceci: ReturnUrl =% 2fDisputes% 2fIndex mais il échoue ici: if (Url.IsLocalUrl (returnUrl) && returnUrl.Length> 1 && returnUrl.StartsWith ("/") &&! returnUrl.StartsWith ("//") &&! returnUrl.StartsWith ("/ \\")) return Redirection (returnUrl); – DotnetSparrow

+0

dans mon action de connexion, j'ai: string decodedUrl = ""; si (! Chaîne.IsNullOrEmpty (returnUrl)) decodedUrl = Server.UrlDecode (returnUrl); if (Url.IsLocalUrl (decodedUrl)) { return Redirection (décodedUrl); } Cela fonctionne pour moi. L'URL est-elle définitivement valide? – Oliver

+0

J'ai mis à jour ma réponse avec ma méthode de poste – Oliver

7

Dans ce cas, vous pouvez faire en sorte que votre action LogOn prenne un paramètre returnUrl et si elle n'est pas vide, au lieu de rediriger vers Home/Index, vous pouvez renvoyer Redirect(returnUrl);. Jetez un coup d'œil à la fonction AccountController par défaut générée par VS lorsque vous créez un nouveau projet. Cela fait exactement cela.

+0

Merci pour la réponse rapide. Je l'ai écrit mais toujours returnUrl est vide dans la méthode d'action. ai-je créé une mauvaise URL de retour dans href? S'il vous plaît suggérer – DotnetSparrow

+0

Vous devrez peut-être encoder url la valeur: 'disputes'. –

+0

non, quelque chose après l'encodage: returnurl dans la méthode d'action de connexion est nulle où querystring comme returnurl comme ceci: public ActionResult Login (modèle LogOnModel, chaîne returnUrl) et/Home/Connexion? ReturnUrl = Disputes% 2FIndex – DotnetSparrow

5

Si le ReturnURL est null, assurez-vous que vous appelez la méthode d'action de la vue comme suit :

// FormMethod.post is optional 
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) 
{ 
    // login view html 
} 

contrôleur de compte:

[AllowAnonymous] 
public ActionResult Login(string returnUrl) 
{ 
    ViewBag.ReturnUrl = returnUrl; 
    return View(); 
} 
+0

Oui, c'est important de bien faire les choses. Pour moi, l'objet anonyme définissant une classe dans mon HTML était utilisé comme objet anon pour les valeurs de routage, donc ReturnUrl ne revenait pas, à la place je voyais 'class' dans les paramètres de requête. Il est préférable de vérifier le balisage final rendu. J'utilise ceci: '@using (Html.BeginForm (" BetaLogin "," Authentification ", nouveau {ReturnUrl = this.Request.Params [" ReturnUrl "]}, FormMethod.Post, nouveau {@class =" o- box-section "}))' –

+0

Définir l'URL de retour sur le formulaire a parfaitement fonctionné pour moi avec un minimum de changements de code. Merci! – BrianLegg

1
 //Utilities   
     public static ReturnUrl GetReturnUrlValues(string returnUrl) 
     { 
      //0:Action,1:Controller,2:Area:,3:Id 
      ReturnUrl vm = new ReturnUrl(); 
      using (TBBSEntities context = new TBBSEntities()) 
      { 
       if (returnUrl != null && returnUrl.Length > 10) 
       { 
        var counterValue = returnUrl.Split('/'); 
        vm.Action = counterValue[0]; 
        vm.Controller = counterValue[1]; 
        vm.Area = counterValue[2] == "0" ? "" : counterValue[2] ; 
        vm.Id = Convert.ToInt32(counterValue[3]); 
        vm.NullStatus = true; 
        return vm; 
       } 
       vm.NullStatus = false; 
       return vm; 
      } 
     } 

     //Controller 
     var transformUrl = Utilities.GetReturnUrlValues(returnUrl); 
      if (transformUrl.NullStatus) 
      { 
      return RedirectToAction(transformUrl.Action, transformUrl.Controller, 
        new { area = transformUrl.Area, id = transformUrl.Id }); 
      } 
      return RedirectToAction("Action", "Controller", new { area = "Area", Id}); 


     //View 
     var returnUrl = "Action/Controller/Area/" + @Model.Id;