Asp.net mvc 如何在ASP.NET MVC中保持URL参数不被替换?
我注意到Stackoverflow登录/注销链接上的returnurl参数没有转义,但当我尝试将path作为参数添加到路由时,它被转义 所以/login?returnurl=/questions/ask shows/login?returnurl=%2fquestions%2fask有点难看。如何使其不转义returnurl值 下面是我在代码中所做的: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
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)。这是迄今为止我看到的唯一合适的答案!