如何在ASP .NET MVC中对URL参数进行编码

8

我在我的视图中有以下代码:

<%= Html.ActionLink(
           "View item", 
           "Index", 
            "Items", 
            new 
            { 
                itemName = Model.ItemName 
            }, 
            null) %>

当商品名称包含井号(#)或百分号(%)时,我遇到了问题。

  • 当商品名称是"name#with#sharp#"时,控制器仅接收名称的第一部分直到第一个井号(只接收"name")。

  • 当商品名称是"name%with%percent"时,我会收到错误信息:HTTP错误400 - 错误请求。

我不确定这是否是URL编码的问题,因为它可以处理其他有冲突字符的情况,例如:

;
=
+
,
~
[blank]

你知道我该如何解决这个问题吗?

提前感谢。


生成了哪些URL?当我尝试使用上面的例子和 '%' 符号时,我得到了这个:http://localhost/AspNetMvc2/Items?itemName=name%25with%25percent,并且没有错误。同样,使用 # 符号的例子会产生这个:http://localhost:55386/Items?itemName=name%23with%23sharp%23 - Jeff Ogata
3个回答

11

假设您已设置路由,并且您的URL看起来像这样:

http://localhost/Items/Index/name%25with%25percent - (这将导致错误)

与以下不同:

http://localhost/Items/Index/?itemName=name%25with%25percent - (查询字符串是可以的)

因此,一种选项是从您的RouteCollection中删除“itemName”属性,以便Html.ActionLink将使用itemName作为QueryString参数呈现Url。

正如@Priyank所说,问题是因为itemName是URL的一部分(而不是查询字符串参数),并且它包含非法字符。


是的,你猜对了。所以唯一可以使用百分号的地方就是查询字符串。是否还有其他方法在URL中使用百分号? - Daniel Peñalba

4
由于这些路由值作为URL字符串的一部分发布,它们将被视为单独的值,用#和%分隔。有几个选项来处理您的情况。
您将需要实现自定义ValueProvider(IValueProvider和特别是RouteDataValueProvider)来处理您的自定义需求。一个程序员在字符'/'方面遇到了问题,并在此处进行了修改http://mrpmorris.blogspot.com/2012/08/asp-mvc-encoding-route-values.html 第二种方法是将值存储在TempData中,该数据持续两个请求并使用它们。
希望这可以帮助您朝着正确的方向思考。

0

您应该能够直接使用视图的UrlHelper实例来完成此操作。尝试一下这个:

<%= Html.ActionLink( "查看项目", "Index", "Items", new { itemName = Url.Encode(Model.ItemName) }, null) %>

更新

经过测试,像我上面那样显式编码似乎不太准确,并且会导致服务器进行双重编码(例如-%将在url中变为%2525)。


1
这还不够。IIS将name+hello转换为name%25%2bhello,导致请求失败。 - Daniel Peñalba
无论我是否进行编码,都能正常运行并返回200状态码。实际上,当我进行编码,只是让路由和IIS正常工作时,它似乎最准确。我已经在Casini和IIS Express中测试了您的URL,包括井号(#)、百分号(%)和加号(+)的示例。您使用的IIS版本是哪个? - JasonOffutt
1
要重现问题,您将需要设置一个名为itemName的令牌路由 - 因此URL看起来类似于:localhost/Items/Index/name%25with%25percent - 此URL包含非法字符。 - Lee Gunn
@LeeGunn 谢谢提示。在我的测试中,具有井号(#)的URL仍然可以使用定义的路由标记正常工作。百分号(%)会触发asp.net请求验证,加号(+)会返回404错误。我尝试了@Priyank建议的修复方法,似乎有效。看来他找到了答案。如果我有声望,我会为他投赞成票。 :) - JasonOffutt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接