让ASP.NET MVC正确地转义路由中的#(hash / pound)字符

时间:2010-02-04 17:47:28

标签: c# asp.net-mvc url-routing

我的路线看起来像这样:

routes.MapRoute(
"BlogTags",
"Blog/Tags/{tag}",
new { controller = "Blog", action = "BrowseTag", viewRss = false }
);

我使用这样的路线创建一个URL:

<%= Html.RouteLink(Html.Encode(sortedTags[i].Tag), 
         new { action = "BrowseTag", tag = sortedTags[i].Tag })%>

但是,当使用带有#字符的标记(如“C#”)时,路由引擎不会对其进行转义,因此我得到一个如下所示的URL:

<a href="/Blog/Tags/C#">C#</a>

我需要的是#swardped,以便它看起来像这样:

<a href="/Blog/Tags/C%23">C#</a>

我在标签进入路线之前尝试在标签上做一个Url.Encode,如下所示:

<%= Html.RouteLink(Html.Encode(sortedTags[i].Tag), 
         new { action = "BrowseTag", tag = Url.Encode(sortedTags[i].Tag) })%>

但这会使路由引擎双重转义#(导致ASP.NET崩溃并出现错误的请求错误)):

<a href="/Blog/Tags/C%2523">C#</a>

如何让路由引擎正确地为我转义#字符?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

作为一个非常光头的解决方案,我会在RouteLink的输出中手动将“#”替换为“%23”。如果你不在你的网址中使用片段,它应该可以工作。

您可以使用正则表达式仅将替换应用于网址的最后一部分。

答案 1 :(得分:0)

我有一个与“/”相关的similar SO question。在研究这个问题时,我了解到ASP.NET在之前解码了URL值,然后将它们传递给MVC框架,并且因为“#”对URL有特殊意义(就像我正在处理的“/”一样) ()基本路由引擎中的某些东西很可能导致这种行为。

与Levi在评论中提到的一样,一种解决方案是使用ASP.NET 4.0。另一个解决方案是编写一个RouteLink助手,自动用一些标记替换“#”(如“!MY_HASH_TOKEN!”),然后在控制器中反转该替换(或者通过某种类型的HttpModule)。

或者,只需抛出标签并将标记值作为查询字符串参数传递。不那么性感,但它简单而有效。