【问题标题】:"The resource cannot be found." error when there is a "dot" at the end of the url“没有找到您要查的资源。” url 末尾有“点”时出错
【发布时间】:2020-06-02 12:20:51
【问题描述】:

我正在使用 ASP .NET MVC Beta,当我使用这个结尾带有“点”的 url 时,我收到 HTTP 404(找不到资源)错误:

http://localhost:81/Title/Edit/Code1.

如果我删除了末尾的点或点位于中间的某个位置,我不会收到错误消息。

我尝试调试,但在 MvcHandler 中的 ProcessRequest 之前,我从“System.Web.CachedPathData.GetConfigPathData(String configPath)”收到错误。

网址末尾是否不允许使用“点”?或者有没有办法修复路由定义来处理这个url?


例如:我有一个名为 Detail1 [Id(integer), Code(string), Description(string)] 的表,它通过它的 Id 列与 Master1 具有 FK 关系。每当我选择 Master1 的记录时,我也会选择它的 Detail1 记录来获取它的 Code 字段。为了不每次都做这个join(因为通常不是只有一个细节,有多个)我选择不使用Id列,我做了Detail1的代码PK。

但是当我摆脱 Id 并使用 Code 作为 PK 时,我的路线也开始使用 Code 字段,例如:Detail1\Edit\Code1

此代码可以包含任何内容或结尾,包括 DOT。在某些情况下,我可以在最后禁止 DOT,但有时它真的很有意义。

而且我也看到了这个post 路线可以非常灵活,所以我不认为我的很奇怪。

所以这就是为什么我做一些如此不标准的事情。有什么建议吗?

还有为什么在 url 末尾有一个 DOT 很奇怪?

【问题讨论】:

  • 不确定这是否仍然适合您,但我为旧 ASP.NET 版本添加了一个实际解决方案,请查看 ;)。
  • 如果您想为您的问题添加更多信息,只需编辑您的问题(单击问题下方的“编辑”链接)。要评论您收到的答案,请使用答案下方的评论工具。如果您发现评论空间不足,您可能应该进行编辑。答案应该就是这样,直接回答您的问题。

标签: .net asp.net-mvc routing routes


【解决方案1】:

如果您使用的是 .NET 4.0,您可以在 web.config 的 system.web 部分中设置此标志,并且将被允许:

<httpRuntime relaxedUrlToFileSystemMapping="true" />

我已经对其进行了测试,并且可以正常工作。 Haack 对此有解释。

【讨论】:

  • 谢谢,升级到 4.0 时会牢记。 .NET 3.5 有办法吗?
  • @Jason:是的,有一种适用于旧 .NET 版本的方法,看看我的回答。
  • 你知道吗?这是否允许以句点结尾的 url 被转发到 iis7.5 中的 url 重写模块?这就是我现在要死的原因
  • 这样做不会有一些安全问题吗?
  • 我不认为这是一个安全问题。根据 MSDN,设置很简单:>“指示 HTTP 请求中的 URL 是否必须是有效的 Windows 文件路径。”
【解决方案2】:

在 1.0 及更高版本的每个 ASP.NET 版本中,可以通过多种方式解决此问题。我知道这个帖子创建已经两年了,但无论如何,它就是这样:

原因

创建自定义错误处理程序或在 IIS 中配置自定义页面以重定向 404 将不起作用。原因是 ASP.NET 认为这个 URL 很危险。在System.Web.Util.FileUtil 内部,ASP.NET 调用私有方法IsSuspiciousPhysicalPath,它尝试将路径映射到(虚拟但合法的)文件名。

当生成的合法路径不等于原始路径时,处理停止并且 ASP.NET 代码返回 404(它不向 IIS 或 web.config 询问自定义 404,它自己返回一个,这很难对此做些什么)。

Windows 资源管理器的工作方式相同。尝试创建一个以一个或多个点结尾的文件名,即test.txt.。您会发现生成的名称是text.txt

ASP.NET中以点结束URL的解决方案

解决方案很简单(一旦你知道,它总是如此)。就在它发出这个 404 之前,它会调用 Application_PreSendRequestHeaders,这是一个简单的事件,您可以在 Global.asax.cs(或 VB 等价物)中注册。以下代码将向浏览器返回一个简单的文本,但也可以进行重定向或任何其他有效响应。

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。将调用该事件。另请注意,某些路径仍然不起作用(例如,以多个点、井号标签或

【讨论】:

  • 这应该也可以在 mvc 中工作吧?那会很好的人。
  • @boomhauer:是的,你是否使用 MVC 并不重要。
  • 太棒了,如果上面的轻松网址不起作用,我会退回到这个。谢谢
  • @boomhauer:这取决于您可以使用哪个版本的 .NET,RelaxedUrl 是否有效。此外,在您需要更多控制权的情况下(例如:拒绝除一种特殊类型之外的所有),更容易保持relaxedUrlToFileSystemMapping="false" 可以为您提供的安全性。
  • @David:确保在 .NET 2.0 CLR 中运行您的 .NET 3.5 应用程序(没有 3.0 或 3.5 CLR)。如果您在 4.0 应用程序池中运行它,当它不起作用时我不会感到惊讶。但我猜你问题的根源。您可能需要针对您的特定场景详细说明和/或创建一个问题。
【解决方案3】:

好吧,在 .NET 4.5 中,我通过在 url 的末尾添加“/”来解决这个问题。

因此,在您的情况下,它将是“http://localhost:81/Title/Edit/Code1./”。这是我唯一做的事情,我不必添加 httpRuntime 设置。

【讨论】:

  • 最后是怎么加/的?
【解决方案4】:

将此添加到处理程序

  <add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
 path="api/*"
 verb="*"
 type="System.Web.Handlers.TransferRequestHandler"
 preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

【讨论】:

    【解决方案5】:

    也许http://localhost:81/Title/Edit/Code1%2E 会起作用。

    我用十六进制 ascii 代码转义了句点。

    【讨论】:

    • 不起作用。大多数浏览器将 %2E 改回 .在发送请求之前,因为它是一个未保留的字符。
    【解决方案6】:

    为什么不能有一个以点结尾的 URI?

    因为 URI 是一个资源请求,并且在所有相关操作系统上都存在 historical imperitive,所以点字符是 extension separator。最后一个点被视为表示文件扩展名,因此点终止没有意义。

    也值得一读:

    【讨论】:

    • RFC3986 对此只字未提。请参阅第 3.3 节,其中明确指出“......路径段被通用语法视为不透明。”
    • 在 URI 中没有扩展分隔符之类的东西。您错误地将文件名与 URI 混淆了。它们不一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    相关资源
    最近更新 更多