2009-02-05 11 views
7

Ich habe bemerkt, dass der Returnurl-URL-Parameter auf den Stackoverflow-Login-/Logout-Links nicht maskiert ist, aber wenn ich versuche, einen Pfad als Parameter zu einer Route hinzuzufügen, wird er maskiert.Wie lassen URL-Parameter in ASP.NET MVC nicht residieren?

Also/login? Returnurl =/fragen/fragen zeigt/login? Returnurl =% 2fquestions% 2fask und es ist irgendwie hässlich. Wie bekomme ich es, um den Rückgabewert nicht zu umgehen?

Hier ist, was ich im Code tun:

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

Würde gerne die Antwort zu diesem auch wissen –

Antwort

1

Ich verstehe einen der Kommentare über die Kodierung aus einem Grund passiert; Dies wäre nur eine Ausnahme, nicht die Regel.

Hier ist was ich zusammengestellt, wie kann es verbessert werden?

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

Funktioniert ein wenig besser, wenn Sie es einen MvcHtmlString zurückgeben. –

0

Mein solutionto ein ähnliches Problem war meine eigene Erweiterung zu schreiben. Nachdem ich im Code herumgegraben habe, konnte ich keinen anderen Weg finden, es anders zu machen. Dein könnte so aussehen.

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(); 
    } 
} 

Ich glaube, ich hatte das gleiche Problem zu machen und mit einem UrlHelper so dass ich stattdessen mit dem string.Format Mechanismus ging. YMMV.

+0

Das einzige Problem mit diesem ist, dass Sie die Route hart-codieren, was bedeutet, dass dies bricht, wenn Sie nicht die Standardroute verwenden. – JMS

+0

Es war nur ein Beispiel von der Spitze meines Kopfes. Wahrscheinlich könnten Sie den UrlHelper verwenden, um die Route von der Aktion/dem Controller zu erstellen und dann die Abfrageparameter an das Ende davon anzuhängen. – tvanfosson

6

Wie bekomme ich es nicht den ReturnUrl Wert

Wie geht um diese zu entkommen?

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

Stellen Sie sicher, dass das, was Sie aber wollen, URL encoding has its purpose.

+1

Schnelle Lösung. Möglicherweise müssen Sie @ Html.Raw (unEncodedUrl) verwenden, wenn Sie JS-Inhalt erstellen –

0

Ich glaube nicht, es gibt einen Weg darum herum, die in den Rahmen integriert ist. Die tatsächliche Konstruktion der URL geschieht in der System.Web.Routing.ParsedRoute.Bind-Methode und es gibt keine Bedingungen, die verwendet werden, um das Entweichen zu verhindern.

Sieht aus wie eine Erweiterungsmethode, aber eine, die etwas robuster als die zuvor erwähnte ist.

1

Der Parameter ist nicht unescaped. Sie werden die URL bemerken:

funktioniert tatsächlich - SO liest und Unescaping diesen Parameter als normal. Wenn Sie andere unzulässige Zeichen wie "&" in den Parameter einfügen möchten, müssen Sie sie dennoch ignorieren.

Der Trick ist lediglich, dass das Zeichen '/' in Abfrageparametern nicht unbedingt% sein muss. Es hat müssen in anderen Kontexten wie in einem Pfad Teil entkommen, so codiert URLEncode immer es, um sicher zu sein.

Wenn Sie möchten, dass die URL nur hübscher aussieht, dann lassen Sie den Parameter einfach als normal entgehen (was Sie tun müssen, um alle anderen Zeichen zu umgehen, die korrekt behandelt werden müssen), und führen Sie dann einen String Replace auf '% 2f' durch "/".

+0

Ich weiß, dass die URL funktionieren wird, aber ich mag den Look nicht, anscheinend haben sich Jeff und die Crew von SO genauso gefühlt. Diese Lösung ist zu viel von einem Hack. – Todd

+0

Es ist garantiert eine gültige URL zu bleiben, wenn Sie nur% 2F in Parametern unescapen. Der obige Code wird über jedes andere Zeichen fallen, das in Parametern nicht gültig ist, z. &, ; oder%. – bobince

+0

Wie gesagt, es ist eine Ausnahme und nicht die Regel. – Todd