当url末尾有一个“点”时,出现“无法find资源”错误
我正在使用ASP .NET MVCtesting版,并得到HTTP 404(资源无法find)错误,当我使用这个URL在最后有一个“点”:
http:// localhost:81 / Title / Edit / Code1 。
如果我删除最后的点或点在中间的某处,我不会得到错误。
我试图debugging,但它在MvcHandler中的ProcessRequest之前从“System.Web.CachedPathData.GetConfigPathData(String configPath)”得到错误。
在url的末尾不允许使用“点”吗? 或者有没有办法解决路线定义来处理这个url?
举个例子:我有一个名为Detail1 [Id(integer),Code(string),Description(string)]的表,通过它的Id列与Master1具有FK关系。 每当我selectMaster1的logging,我也select它的Detail1logging来得到它的代码字段。 为了不每次都进行这个连接(因为通常不只有一个细节,所以不止一个)我select不使用Id列,并且我创build了Detail1的Code PK。
但是,当我摆脱Id和使用代码作为PK,然后我的路线也开始与代码字段,如:Detail1 \ Edit \ Code1
这个守则可以有任何东西或最后,包括DOT。 有些情况下,我可以在最后禁止DOT,但有时候确实有意义。
而且我也看到这个post ,路线可以非常灵活,所以我不认为我的太奇怪了。
所以这就是为什么我做非标准的事情 有什么build议么?
而且为什么在一个url结尾处有一个DOT这么奇怪呢?
如果您使用.NET 4.0,则可以在web.config的system.web部分中设置此标志,并允许:
<httpRuntime relaxedUrlToFileSystemMapping="true" />
我已经testing过它,它工作。 哈克有一个解释。
这可以在1.0和以上的每个ASP.NET版本中以几种方式解决。 我知道这是线程创build两年后,但无论如何,在这里:
原因
创build自定义error handling程序或在IIS中configuration自定义页面以redirect404将不起作用。 原因是ASP.NET认为这个URL很危险。 在System.Web.Util.FileUtil
内部,ASP.NET调用私有方法IsSuspiciousPhysicalPath
,该方法试图将path映射到(虚拟但是合法的)文件名。
当生成的合法化path不等于原始path时,处理将停止,并且ASP.NET代码将返回404(它不会询问IIS或web.config用于自定义404,而是自己返回一个,这使得它很难做到这一点)。
Windows资源pipe理器的工作方式相同。 尝试创build一个以一个或多个点结尾的文件名,即test.txt.
。 你会发现结果的名字是text.txt
。
在ASP.NET中以点结尾URL的解决scheme
解决scheme很简单(一旦你知道它,它总是)。 就在它发出这个404之前,它将调用Application_PreSendRequestHeaders
,这是一个简单的事件,你可以在Global.asax.cs
(或VB的等价物)中注册。 下面的代码将返回一个简单的文本到浏览器,但redirect或任何其他有效的响应也是可能的。
protected void Application_PreSendRequestHeaders(object sender, EventArgs e) { HttpResponse response = this.Context.Response; HttpRequest request = this.Context.Request; if (request.RawUrl.EndsWith(".")) { response.ClearContent(); response.StatusCode = 200; response.StatusDescription = "OK"; response.SuppressContent = false; response.ContentType = "text/plain"; response.Write("You have dot at the end of the url, this is allowed, but not by ASP.NET, but I caught you!"); response.End(); } }
注意:这个代码也适用于“aspx” 不是 URL的一部分。 即, http://example.com/app/somepath 。 将调用该事件。 还要注意,有些path仍然不起作用(例如以多个点结束,使用散列标签或<-sign,导致400-错误请求)。 再次,它的工作结束于一个报价,一个空格+斜杠或用空格分隔的多个点。
那么,在.NET 4.5中,我通过在URL的末尾添加“/”来解决这个问题。
所以,你的情况是“http:// localhost:81 / Title / Edit / Code1。/”。 这是我做的唯一的事情,我不必添加httpRuntime设置。
添加到处理程序
<add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi" path="api/*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers>
也许http://localhost:81/Title/Edit/Code1%2E
会工作。
我用hexASCII代码逃脱了这段时间。
为什么你不能有一个点终结的URI?
由于URI是资源请求,并且在所有相关的操作系统上都存在一个历史的缺陷 ,即点字符是扩展分隔符 。 最后一个点被视为表示文件扩展名,因此点终止是没有意义的。
另外值得一读:
- RFC1738
- RFC3986