【问题标题】:Current working directory in ASP.NET code-behinds - can we depend on it?ASP.NET 代码隐藏中的当前工作目录 - 我们可以依赖它吗?
【发布时间】:2010-09-10 21:37:16
【问题描述】:

我们可以依赖 ASP.NET 代码隐藏中的当前工作目录吗?或者,换句话说,我们可以使用相对路径,并确保它们会起作用吗?

如果在网站的一个页面中,我将当前工作目录设置为特定的内容,下次加载网站上的另一个页面时它是否仍然相同?何时加载网站上的同一页面?

如果我在 Page_Load() 中将当前工作目录设置为特定的内容,我能否确定在调用 Page_PreRender() 时它仍然是相同的?或者同一网站上的另一个页面可以在我之间改变它吗?同一个应用程序池中不同网站上的页面可以改变我吗?不同应用程序池中不同网站的页面?

换句话说,在 IIS 中,当前工作目录的范围是什么?它是特定于页面的吗?它是特定于网站的吗?还是在应用程序池中的所有页面之间共享?

在页面、网站、应用程序池和服务器之间,隔离当前工作目录不同值的边界在哪里?

【问题讨论】:

  • 为什么要利用 Web 服务器上的当前工作目录?我不明白这有什么意义。工作目录是启动 w3wp.exe 时使用的目录——这有什么关系?
  • 从代码隐藏中,我们正在访问一个 .NET 程序集,该程序集是为在 Web 和桌面应用程序之间提供共享功能而编写的。用户可以通过桌面应用程序提交工作,或者用户可以通过网站提交工作。在任何一种情况下,作业的处理都由 .NET 程序集处理,并通过将文件写入通过相对路径访问的多个队列目录之一来完成。问题是我们是否需要重写程序集中的所有文件处理以使其与 IIS 可靠地工作。
  • 你不需要重写任何东西。这些目录将相对于它们所在站点的根目录。
  • "如果在网站的一个页面中,我将当前工作目录设置为特定的内容" 你如何“设置”页面的当前目录?

标签: asp.net iis


【解决方案1】:

AppDomain.CurrentDomain.RelativeSearchPath 将为您提供 bin 文件夹的物理路径

【讨论】:

    【解决方案2】:

    Environment.CurrentDirectoryGetCurrentDirectorySetCurrentDirectory winapi 函数的简单包装器。实际上,尝试设置目录需要 UnmanagedCode 权限。每当一个功能阻止您的网站在部分信任下运行时,您应该警惕依赖它。 :)

    来自SetCurrentDirectory 文档:

    为当前进程更改当前目录

    我能找到的关于w3wp.exe 进程和 ASP.NET 站点之间关系的最佳解释是this answer。您网站中的任何其他页面可能更改您页面的当前工作目录。同一应用程序池下的任何其他站点上的任何页面可能更改您页面的当前工作目录。这些对当前工作目录的外部更改可能在页面执行期间的任何时间发生。另一方面,不同应用程序池下的站点上的页面不会更改页面的当前工作目录。我说“可能”的原因是,如果您考虑网络花园场景,它会变得更加复杂,其中一个 ASP.NET 站点可能有多个进程。

    现在考虑SetCurrentDirectory 不是线程安全的:

    多线程应用程序和共享 库代码不应使用 SetCurrentDirectory 函数和 应避免使用相对路径 名字。当前目录状态 由 SetCurrentDirectory 编写 函数存储为全局 每个过程中的变量,因此 多线程应用程序不能 可靠地使用这个值而不 其他可能的数据损坏 也可能正在阅读的线程或 设置这个值。这个限制 也适用于 获取当前目录和 GetFullPathName 函数。这 例外是当应用程序 保证在一个运行 单线程,例如解析 命令行中的文件名 主线程中的参数字符串 在创建任何额外的 线程。在中使用相对路径名 多线程应用程序或共享 库代码可能会产生不可预测的 结果,不支持。

    您可能不想依赖当前的工作目录。话虽如此,鉴于依赖当前工作目录是多么愚蠢,您可以合理地确定没有其他代码会触及它。 :) 快速浏览一下 Reflector 表明没有 .NET 框架代码会更改它。不过,有一些功能会检查它,所以要小心那些。如果您控制部署环境,则可以确保您的站点在其自己的应用程序池中运行。通过适当的同步技术,您应该能够安全地更新当前工作目录。不过,除了 hack,我不会将其视为其他任何东西。

    【讨论】:

      【解决方案3】:

      应使用波浪号 (~) 运算符相对于站点根目录创建链接:

      <a href="~/mysite/somepage.aspx" id="someLink" runat="server">Some Page</a>
      

      在服务器中,应用程序池将您的站点完全隔离开,这样即使其他站点在同一台服务器上崩溃,也不会因此而导致您的站点瘫痪。 IIS 几乎是特定于站点的,具有应用程序池的附加隔离优势。我认为尝试从另一个页面的代码隐藏更改一个页面上的链接没有实际用途(或者我可能不太理解这个问题)。

      这里是 IIS 架构的总结:

      http://learn.iis.net/page.aspx/243/aspnet-integration-with-iis-7/

      【讨论】:

      • 我不是在谈论链接,我是在谈论文件系统。
      • 您明确询问了相对路径。我认为您需要重新表述这个问题。
      猜你喜欢
      • 2017-07-09
      • 2022-01-18
      • 2015-04-03
      • 1970-01-01
      • 2010-10-15
      • 2019-03-28
      • 1970-01-01
      • 2012-09-22
      • 2012-01-23
      相关资源
      最近更新 更多