7

我注意到 Stackoverflow 登录/注销链接上的 returnurl URL 参数没有被转义,但是当我尝试将路径作为参数添加到路由时,它会被转义。

所以 /login?returnurl=/questions/ask 显示 /login?returnurl=%2fquestions%2fask 有点丑。如何让它不逃避 returnurl 值?

这是我在代码中所做的:

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

5 回答 5

7

如何让它不逃避 returnurl 值

这个怎么样?

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

但请确保这是您想要的,URL 编码有其目的。

于 2009-02-05T08:57:44.237 回答
1

我理解关于编码发生的评论之一是有原因的;这只是一个例外,而不是规则。

这是我整理的,如何改进?

    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);
    }
于 2009-02-05T13:34:06.360 回答
1

该参数不是未转义的。您会注意到 URL:

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

确实有效 - SO 正在正常读取和取消转义该参数。如果您想在参数中包含其他越界字符,例如“&”,您仍然必须对它们进行转义。

诀窍仅仅是“/”字符不需要在查询参数中进行 % 转义。它确实必须在其他上下文中进行转义,例如在路径部分中,因此 URLEncode 总是对其进行编码,以确保安全。

如果您只是想让 URL 看起来更漂亮,只需像往常一样转义参数(您必须这样做以转义必须正确处理的所有其他字符),然后用 '/' 对 '%2f' 进行字符串替换。

于 2009-02-05T13:37:20.253 回答
0

我对类似问题的解决方案是编写自己的扩展。在挖掘代码之后,我找不到其他方法。你的可能看起来像这样。

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

我想我在制作和使用 UrlHelper 时遇到了同样的问题,所以我改用了 string.Format 机制。YMMV。

于 2009-02-05T03:58:53.717 回答
0

我不相信框架中内置了一种解决方法。URL 的实际构造发生在 System.Web.Routing.ParsedRoute.Bind 方法中,并且没有任何条件用于防止转义。

看起来扩展方法是可行的方法,但比前面提到的方法更健壮。

于 2009-02-05T12:19:04.750 回答