Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to leave URL parameters unescaped in ASP.NET MVC?

I've noticed the returnurl URL parameter on the Stackoverflow login/logout links are not escaped but when I try to add path as a parameter to a route it gets escaped.

So /login?returnurl=/questions/ask shows /login?returnurl=%2fquestions%2fask and it's kind of ugly. How do I get it to not escape the returnurl value?

Here's what I'm doing in the code:

Html.ActionLink("Login", "Login", "Account", new { returnurl=Request.Path }, null)
like image 677
Todd Avatar asked Feb 05 '09 03:02

Todd


People also ask

How hide parameter value in url in MVC?

You cannot hide parameters. Even if you use the post method instead of the get method to remove parameters from the url. You can still see the passed parameters in the request message. The way to safely hide parameters is to encrypt them.

How do I change the default url in MVC?

How do I change the default page in ASP NET MVC? You can set up a default route: routes. MapRoute( "Default", // Route name "", // URL with parameters new { controller = "Home", action = "Index"} // Parameter defaults ); Just change the Controller/Action names to your desired default.

What is attribute routing in asp net core?

With attribute-based routing, we can use C# attributes on our controller classes and on the methods internally in these classes. These attributes have metadata that tell ASP.NET Core when to call a specific controller. It is an alternative to convention-based routing.

What is the use of url action?

Use Url. Action when you need to generate only an url (this could also be used in a controller action).


3 Answers

How do I get it to not escape the returnurl value

How's about this?

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

Be sure that's what you want though, URL encoding has its purpose.

like image 135
Buu Nguyen Avatar answered Oct 01 '22 06:10

Buu Nguyen


I understand one of the comments about encoding happening for a reason; this would only be an exception, not the rule.

Here's what I put together, how can it be improved?

    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);
    }
like image 40
Todd Avatar answered Oct 01 '22 05:10

Todd


The parameter is not unescaped. You'll notice the URL:

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

does actually work - SO is reading and unescaping that parameter as normal. If you wanted to include other out-of-bounds characters such as '&' in the parameter you would still have to escape them.

The trick is merely that the '/' character in particular does not need to be %-escaped in query parameters. It does have to be escaped in other contexts such as in a path part, so URLEncode always encodes it, to be safe.

If you just want the URL to look prettier, simply escape the parameter as normal (which you must do to escape all the other characters that must be handled correctly), and then do a string replace on '%2f' with '/'.

like image 45
bobince Avatar answered Oct 01 '22 06:10

bobince