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

Asp.net mvc 如何在ASP.NET MVC中保持URL参数不被替换?,asp.net-mvc,routes,urlencode,Asp.net Mvc,Routes,Urlencode,我注意到Stackoverflow登录/注销链接上的returnurl参数没有转义,但当我尝试将path作为参数添加到路由时,它被转义 所以/login?returnurl=/questions/ask shows/login?returnurl=%2fquestions%2fask有点难看。如何使其不转义returnurl值 下面是我在代码中所做的: Html.ActionLink("Login", "Login", "Account", new { returnurl=Request.Pat

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

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

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

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

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

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

我怎样才能让它不逃过 返回URL值

这个怎么样

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

不过,请确保这是您想要的,

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


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

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

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

    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);
    }
publicstaticstringactionlinknoescape(此HTMLHelperHTML、stringlinktext、stringactionName、stringcontrollerName、对象值、对象htmlAttributes)
{
RouteValueDictionary routeValues=新的RouteValueDictionary(值);
RouteValueDictionary htmlValues=新的RouteValueDictionary(htmlAttributes);
UrlHelper UrlHelper=新的UrlHelper(html.ViewContext.RequestContext,RouteTable.Routes);
字符串url=urlHelper.Action(actionName,controllerName);
url+=“?”;
List paramList=新列表();
foreach(RouteValue中的KeyValuePair对)
{
对象值=对。值??“”;
Add(String.Concat(pair.Key,“=”,Convert.ToString(value,CultureInfo.InvariantCulture));
}
url+=String.Join(&),paramList.ToArray();
标记生成器=新标记生成器(“a”);
builder.InnerHtml=string.IsNullOrEmpty(linkText)?“”:HttpUtility.HtmlEncode(linkText);
合并属性(HtmlValue);
builder.MergeAttribute(“href”,url);
返回builder.ToString(TagRenderMode.Normal);
}
该参数未取消扫描。您会注意到URL:

http://stackoverflow.com/users/login?returnurl=%2fquestions%2fask
确实有效——正常读取和取消该参数也是如此。如果希望在参数中包含其他越界字符,如“&”,则仍然必须对其进行转义

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


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

希望知道这个问题的答案。唯一的问题是,您正在对路由进行硬编码,这意味着,如果你不使用默认路线,这将中断。这只是我脑海中的一个例子。也许您可以使用UrlHelper从action/controller构建路由,然后将查询参数附加到它的末尾。我知道URL可以工作,但我不喜欢它的外观,显然Jeff和crew的感觉是一样的。此解决方案太难了。如果您只在参数中unescape%2F,它将保证保持有效的URL。您上面的代码将落在参数中无效的任何其他字符上,例如&;或者%.就像我说的,这是一个例外而不是规则。如果让它返回一个MvcHtmlString.Quick解决方案,效果会更好一些。如果要创建任何JS内容,可能必须使用@Html.Raw(unEncodedUrl)。这是迄今为止我看到的唯一合适的答案!