当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