2009-02-05 12 views
7

J'ai remarqué que le paramètre d'URL returnurl sur les liens de connexion/déconnexion de Stackoverflow n'est pas échappé mais lorsque j'essaie d'ajouter un chemin en tant que paramètre à un itinéraire, il est échappé. Donc/login? Returnurl =/questions/ask shows/login? Returnurl =% 2fquestions% 2fask et c'est plutôt moche. Comment puis-je l'obtenir pour ne pas échapper la valeur de retour?Comment laisser les paramètres d'URL non échappés dans ASP.NET MVC?

Voici ce que je fais dans le code:

Html.ActionLink("Login", "Login", "Account", new { returnurl=Request.Path }, null) 
+0

Vous aimeriez connaître la réponse à cette question –

Répondre

1

Je comprends un des commentaires sur l'encodage qui se passe pour une raison; ce ne serait qu'une exception, pas la règle.

Voici ce que j'ai mis ensemble, comment peut-il être amélioré?

public static string ActionLinkNoEscape(this HtmlHelper html, string linkText, string actionName, string controllerName, object values, object htmlAttributes) 
    { 
     RouteValueDictionary routeValues = new RouteValueDictionary(values); 
     RouteValueDictionary htmlValues = new RouteValueDictionary(htmlAttributes); 

     UrlHelper urlHelper = new UrlHelper(html.ViewContext.RequestContext, RouteTable.Routes); 
     string url = urlHelper.Action(actionName, controllerName); 
     url += "?"; 
     List<string> paramList = new List<string>(); 
     foreach (KeyValuePair<string, object> pair in routeValues) 
     { 
      object value = pair.Value ?? ""; 
      paramList.Add(String.Concat(pair.Key, "=", Convert.ToString(value, CultureInfo.InvariantCulture))); 
     } 
     url += String.Join("&", paramList.ToArray()); 

     TagBuilder builder = new TagBuilder("a"); 
     builder.InnerHtml = string.IsNullOrEmpty(linkText) ? "" : HttpUtility.HtmlEncode(linkText); 
     builder.MergeAttributes<string, object>(htmlValues); 
     builder.MergeAttribute("href", url); 
     return builder.ToString(TagRenderMode.Normal); 
    } 
+0

Fonctionne un peu mieux si vous l'avez renvoyer un MvcHtmlString. –

0

Mon solutionto un problème similaire était d'écrire ma propre extension. Après avoir creusé dans le code je ne pouvais pas trouver un moyen de le faire autrement. Le vôtre pourrait ressembler à ceci.

public static class HtmlHelperExtensions 
{ 
    public static string LoginLinkWithReturnUrl(this HtmlHelper helper, 
               string linkText, 
               string action, 
               string controller, 
               string returnUrl, 
               object htmlAttributes) 
    { 
     TagBuilder builder = new TagBuilder("a"); 
     builder.Attributes.Add("href", 
            string.Format("/{0}/{1}?returnurl={2}", 
               controller, 
               action, 
               returnUrl)); 
     var attrDict = new RouteValueDictionary(htmlAttributes); 
     builder.MergeAttributes(attrDict); 
     builder.InnerHtml = linkText; 
     return builder.ToString(); 
    } 
} 

Je pense que j'ai eu le même problème et faire en utilisant un UrlHelper alors je suis allé avec le mécanisme de string.Format à la place. YMMV.

+0

Le seul problème avec ceci est que vous êtes en train de coder en dur l'itinéraire, ce qui signifie que cela va casser si vous n'utilisez pas la route par défaut. – JMS

+0

C'était juste un exemple sur le dessus de ma tête. Vous pouvez probablement utiliser UrlHelper pour créer la route à partir de l'action/du contrôleur, puis ajouter les paramètres de la requête à la fin de celle-ci. – tvanfosson

6

Comment puis-je obtenir pour échapper à la valeur ne ReturnUrl

Comment est à ce sujet?

var url = Url.Action("Login", "Account", new {returnurl = Request.Path}); 
var unEncodedUrl = HttpUtility.UrlDecode(url); 
Response.Write("<a href='" + unEncodedUrl + "'>...</a>"); 

Assurez-vous que ce que vous voulez bien, URL encoding has its purpose.

+1

Solution rapide. Peut-être utiliser @ Html.Raw (unEncodedUrl) si vous créez un contenu JS –

0

Je ne crois pas qu'il y ait un moyen de contourner qui est intégré dans le cadre. La construction réelle de l'URL se produit dans la méthode System.Web.Routing.ParsedRoute.Bind et aucune condition n'est utilisée pour empêcher l'échappement.

On dirait qu'une méthode d'extension est la méthode à suivre, mais elle est légèrement plus robuste que celle mentionnée précédemment.

1

Le paramètre est pas non échappés. Vous remarquerez l'URL:

http://stackoverflow.com/users/login?returnurl=%2fquestions%2fask 

fonctionne en fait - SO est la lecture et déséchapper ce paramètre comme normal. Si vous vouliez inclure d'autres caractères hors limites tels que '&' dans le paramètre, vous devrez quand même leur échapper.

L'astuce est simplement que le caractère '/' en particulier n'a pas besoin d'être% -escapé dans les paramètres de requête. Il doit être échappé dans d'autres contextes tels que dans une partie de chemin, donc URLEncode l'encode toujours, pour être sûr. Si vous voulez juste que l'URL soit plus jolie, évitez simplement le paramètre comme normal (que vous devez faire pour échapper tous les autres caractères qui doivent être manipulés correctement), et ensuite remplacez une chaîne sur '% 2f' par '/'.

+0

Je sais que l'URL fonctionnera mais je n'aime pas le look, apparemment Jeff et l'équipe de SO ont ressenti la même chose. Cette solution est trop d'un hack. – Todd

+0

Il est garanti que vous resterez une URL valide si vous ne désactivez que% 2F dans les paramètres. Votre code ci-dessus tombera sur tout autre caractère qui n'est pas valide dans les paramètres, par exemple. &, ; ou%. – bobince

+0

Comme je l'ai dit, c'est une exception et non la règle. – Todd