在 ASP.NET/IIS 的 url 中使用冒号 (:)
Posted
技术标签:
【中文标题】在 ASP.NET/IIS 的 url 中使用冒号 (:)【英文标题】:Using a colon (:) in a url with ASP.NET/IIS 【发布时间】:2010-10-14 14:58:16 【问题描述】:我正在 ASP.NET MVC 中实现一个自定义控制器,真的希望能够在 url 中使用冒号,以便我可以识别类/列名称及其值,例如所以:
http://example.com/user:chaiguy
...但显然 ASP.NET 或 IIS 不允许在 url 中使用冒号。我做了一些挖掘,显然这被认为是一个安全问题,但是,我正在使用 MVC 并手动处理 all url 路径(只是将它们视为字符串),而不是将它们与文件系统相关联,所以我很确定这不适用。
我还听到一些关于实现自定义 Http 处理程序或其他内容的讨论。
任何想法或想法将不胜感激。
呃....为什么?说真的,为什么要打破标准? ——兰多夫
...
那么,我建议您研究构建 Web 服务。 WCF 是一种很好的技术,它在 IIS 中很好地托管。
我碰巧喜欢 url,而 WCF 对我来说太复杂了。我希望它像 REST 一样与 url 兼容,但不仅仅能够导航层次结构,或者做布局合理的事情。我对 /users/chaiguy 的问题是它正在解释没有层次结构:在我的系统中,“用户”是一个类,它不是一个文件夹。 user:chaiguy 表示值为“chaiguy”的用户类的实例,它是一个单一实体,具有子实体的潜力。比如:
/user:chaiguy/name
...我想显示该实体的名称。如果我用你的方法做到这一点,它会是这样的:
/users/chaiguy/name
问题是你怎么知道什么是类和价值是什么?可以理解为
/users/chaiguy:name
在我的系统中,这没有意义。看看我在说什么?举一个稍微复杂一点的例子,假设我们想从多个实例中选择用户实体的一个子实体。因此,一个用户可能有多个电子邮件地址。要选择一个,我们可以使用:
/user:chaiguy/email:me@here.com/
所以它实际上是递归的。它不是文件路径,它更像是 XPath(或者可能类似于 jQuery,基于我对它的了解甚少)。也就是说,它更像是动态评估的查询选择,而不是硬连线的文件路径。它在服务器上进行评估。
别搞错了,我不是在这里建立一个典型的网站甚至网络服务。
【问题讨论】:
什么版本的 IIS? 6? 老实说,我现在只是在 ASP.NET 开发服务器中运行它,不能 100% 确定我的实际 Web 主机正在运行什么。 啊。然后冒号会在碰到 HttpHandler 之前被拦截。所以你可能是 S.O.L. 有同样的问题,我注意到,***在路径段中使用冒号:2001: A Space Odyssey。他们不是互联网上排名第三的网站吗?另请注意,在 Firefox 中,如果您复制地址,它会编码括号而不是冒号。然而,如果你调用 encodeURIComponent(':'),你会得到 "%3A"。那是我的试金石。冒号是禁区(太糟糕了,我也有这个用处)。 确实,***到处都使用冒号,即使是在没有明显好处的非常显眼的地方,例如他们的contact us 页面。你想知道,如果它如此危险,他们如何逃脱它?当然,我知道 wikipedia 不使用 .NET,但问题(无论如何对我来说)确实围绕冒号是否是 URL 中的 合法 字符,无论平台如何。 【参考方案1】:更改web.config中httpRuntime
的requestPathInvalidCharacters
属性:
<httpRuntime maxRequestLength="20480" requestValidationMode="2.0" requestPathInvalidCharacters="" maxQueryStringLength="20480" />
并且 ASP.NET 不应再阻止您的请求路径中的冒号。
【讨论】:
这样安全吗?我们是否只想删除冒号而不是其他字符? 这不适用于 ASP.Net 4。即使是requestValidationMode="2.0"
。
这个应该放到configuration > system.web > httpRuntime
。【参考方案2】:
在这里回答了类似的问题:https://***.com/a/12037000/134761
似乎 ASP.net 不允许在“?”之前使用冒号。在 URL 中,即使它被编码为 %3A。
例如,这些不起作用:
http://foo.org/api/persons/foo:bar
http://foo.org/api/persons/foo%3abar
但这有效:
http://foo.org/api/persons?id=foo%3abar
在所有示例中,我们希望 ASP.NET MVC 将“foo:bar”作为 id 参数传递,并正确解码。我刚刚用 MVC4 测试了这个,它似乎工作。令人讨厌的是它不接受问号之前的 URL 编码,但我确信这是有充分理由的。可能是为了让问号之前的所有内容都是有效的 URL 以及问号之后的任何参数。
【讨论】:
实际上http://foo.org/api/persons?id=foo:abar
也可以正常工作-无需转义冒号。
正如我所说,这条规则似乎只适用于路径,即问号左侧的所有内容。问号右侧允许冒号。【参考方案3】:
尝试设置 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters\AllowRestrictedChars。这是来自http://support.microsoft.com/?id=820129。我不知道 ASP.NET/MVC 是否自己做一些检查,但如果只是 http.sys 阻止你,这应该可以解决它。
【讨论】:
此时冒号在 URL 中是否有效?如果没有,那么就不要这样做,因为 http.sys 不会是唯一不喜欢它的软件。【参考方案4】:这个 web.config 设置对我有用。它在 url 中接受冒号 (:)。
<httpRuntime targetFramework="4.6.1" requestPathInvalidCharacters=""/>
【讨论】:
【参考方案5】:我建议你重新考虑你想做什么。使用路径来指示上下文并隐藏您的类和字段名称,将 URL 路径中的特定上下文映射到类名称和字段。例如,如果您需要指定用户,请构建您的 URL 布局,例如 example.com/users/chaiguy
而不是 example.com/user:chaiguy
。
【讨论】:
我意识到这是一个选择并感谢这个建议,但我真的很想这样做。如果我不能使用冒号,我最终可能会使用不同的符号,但冒号是最理想的。 因为我想做的很不一样,并且涉及到基于 url 的与非 web 系统的交互。 那么,我建议您调查构建 Web 服务。 WCF 是一种很好的技术,它在 IIS 中很好地托管。【参考方案6】:实际上有可用的 WCF REST,您可以使用 WCF Starter Kit here 在一个小时内轻松启动并运行。这利用了 REST 的强大功能并将其与 WCF 的易用性相结合。此外,使用 WCF,您还可以创建自己的传输层,如果您需要它可以以任何您希望的方式解释 URL。关于初学者工具包的一个有趣的事情是它允许在 Url 中使用空格,这实际上给真正的 REST fundi 带来了一些麻烦。
由于 WCF,我并不热衷于查看它,但您真的不需要知道那么多。该解决方案创建您需要的一切,只需添加代码。
【讨论】:
您不是说 WCF 的强大功能和 REST 的易用性吗? ;)【参考方案7】:我建议使用句号。基于 HTTP 协议的 REST 是一个为 HTTP 构建新用途的示例,该用途符合标准并且非常成功。也许你可以这样做。
和一个“。”在许多语言中是标准的“class.method”或“class.attribute”。
现在ME,我想在URL参数中使用冒号,有些地方正在这样做。我还得看看能不能摆脱它。
PS,对我来说,我可能会使用这个: http://www.businesscasualblog.com/2009/07/how-to-share-a-link-to-a-specific-timecode-in-youtube-video.html
本质上是'--h--m--s'
【讨论】:
【参考方案8】:网址中的冒号有效吗?简答否。
长答案,是的,如果它在一个 url fragment 中。
示例:http://site/gwturl#user:45/comments
(注意冒号是井号标签)
来源
这个答案, Is a colon safe for friendly-URL use? 以及个人测试,只需将:
添加到 ASP.NET 中的 url 并使用A potentially dangerous Request.Path value was detected from the client (:)
获取 YSOD
【讨论】:
-1 冒号在 URL 中有效。检查grammar of RFC 2396,由HTTP 1.1 spec 或grammar of the newer RFC 3986 引用。你会发现冒号在路径和查询中也是有效的。 @EugeneBeresovksy meh 我支持我的回答,特别是最后一点。 回复:你的最后一点。 OP意识到了这个问题,这就是他问的原因。我链接到显示冒号有效的相关 RFC。事实上,片段中的冒号可能会成为问题 (depending on the HTML version used)。也就是说,各种 HTTP 和 HTML 规范有时会发生冲突,但一般来说,冒号是有效的。 asp.net 不喜欢它们并试图提供一些伪安全(幸运的是可以使用requestPathInvalidCharacters
标志关闭)是另一回事。以上是关于在 ASP.NET/IIS 的 url 中使用冒号 (:)的主要内容,如果未能解决你的问题,请参考以下文章
Jquery AJAX ASP.NET IIS 跨域 超简单解决办法