代码之家  ›  专栏  ›  技术社区  ›  Todd

如何在ASP.NET MVC中保持URL参数不被替换?

  •  7
  • Todd  · 技术社区  · 16 年前

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

    所以/login?returnurl=/questions/ask shows/login?returnurl=%2fquestions%2fask有点难看。如何使其不转义returnurl值?

    下面是我在代码中所做的:

    Html.ActionLink("Login", "Login", "Account", new { returnurl=Request.Path }, null)
    
    5 回复  |  直到 16 年前
        1
  •  7
  •   Buu    16 年前

    我怎样才能让它不逃过

    这个怎么样?

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

    但要确保这就是你想要的, URL encoding has its purpose.

        2
  •  1
  •   Todd    16 年前

    我理解其中一条关于编码的评论是有原因的;这只是一个例外,不是规则。

    以下是我总结的,如何改进?

        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);
        }
    
        3
  •  1
  •   bobince    16 年前

    参数为 没有替罪羊。您会注意到URL:

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

    确实有效——正常读取和取消该参数也是如此。如果要包含其他越界字符,如“&”在参数中,您仍然必须转义它们。

    诀窍仅仅是在查询参数中不需要特别转义“/”字符。信息技术

    如果您只是想让URL看起来更漂亮,只需按正常方式转义参数(必须这样做才能转义所有其他必须正确处理的字符),然后用“/”替换“%2f”上的字符串。

        4
  •  0
  •   tvanfosson    16 年前

    我解决类似问题的方法是编写自己的扩展。在深入研究代码之后,我找不到其他方法来实现它。你的可能看起来像这样。

    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。

        5
  •  0
  •   Todd    16 年前

    我不相信有一种方法可以绕过这个框架。URL的实际构造发生在System.Web.Routing.ParsedLote.Bind方法中,没有任何条件用于阻止转义。

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