【问题标题】:Attempt to create 'Virtual Directory' creates 'Virtual Application' instead尝试创建“虚拟目录”会创建“虚拟应用程序”
【发布时间】:2012-01-26 22:59:15
【问题描述】:

我有一个 Web 应用程序,它在 IIS 虚拟应用程序下部署了两个虚拟目录。在 IIS 6 机器上,以下代码按预期创建了这些虚拟目录,但是在 IIS 7 机器上,我的虚拟应用程序下有两个其他虚拟应用程序,而不是一个虚拟应用程序下有两个虚拟目录。我尝试了以下两种方法,但都仍然创建虚拟应用程序,而不是虚拟目录。如何更改此代码以部署所需的虚拟目录,而不是不需要的虚拟应用程序?

一个:

private void AddVirtualDir(DirectoryEntry entry)
{
    DirectoryEntry virtualDirectory = (DirectoryEntry)entry.Invoke("Create", "IIsWebVirtualDir", "VirtualDirectory");
    virtualDirectory.InvokeSet("Path", @"VirtualPath");
    virtualDirectory.InvokeSet("AppFriendlyName", "VirtualDirectory");
    virtualDirectory.Properties["AccessRead"][0] = true;
    virtualDirectory.Properties["AccessScript"][0] = 512;
    virtualDirectory.Properties["AppIsolated"].Clear();
    virtualDirectory.Properties["AppIsolated"].Add(2);
    virtualDirectory.Invoke("AppCreate", false);
    virtualDirectory.CommitChanges();
    entry.CommitChanges();
}

两个:

private void AddVirtualDir(DirectoryEntry entry)
{
    var virtualDirectory = entry.Children.Add("VirtualDirectory", "IIsWebVirtualDir");
    virtualDirectory.Properties["AccessRead"][0] = true;
    virtualDirectory.Properties["AccessScript"][0] = 512;
    virtualDirectory.Properties["AppFriendlyName"][0] = "EditorControls";
    virtualDirectory.Properties["AppIsolated"][0] = 2;
    virtualDirectory.Properties["Path"][0] = Path.Combine(_INSTALLDIR, @"Kryptiq_Root\FormManagement\EditorControls");
    virtualDirectory.CommitChanges();
    entry.CommitChanges();
}

【问题讨论】:

  • 您能否发布一张在 IIS6 中的截图(记得展开所有必要的节点),我无法确定它应该是什么样子。也给出了两个例子,你尝试过这两种不同的东西吗?
  • 是的,这两种不同的东西是我尝试过的两种不同的方式。您的建议在 IIS 7 上效果很好。目前,似乎 IIS 6 没有设置我正在调查的 asp.net 扩展。
  • 在与 QA 交谈时,当前的 IIS 6 问题似乎不涉及此更改的虚拟目录。创建的整个虚拟应用程序没有 .net 扩展名。我正在调查与此更改无关的配置文件的其他代码更改。

标签: c# asp.net iis-7


【解决方案1】:

这是如何在 IIS6 上工作的

这里的问题是您正在设置AppIsolated 值。在 IIS6 中,它用于配置应用程序的运行方式,通常您永远不需要触摸它或将其添加到任何地方。

AppIsolated 始终默认为2,这意味着池化进程,即应用程序将在父应用程序的应用程序池或AppPoolId 指定的池中运行。

存在其他值的原因是,您可以将应用程序配置为在几个旧 IIS5 模式下运行 - 进程内和进程外模式。

因此,除非您将站点的 /root 应用程序配置为以 AppIsolated="2" 以外的任何方式运行,否则您不需要设置此值。

您的代码可以很简单:

using (var entry = new DirectoryEntry("IIS://localhost/W3SVC/1/ROOT"))
{
  using (DirectoryEntry virtualDirectory = entry.Children.Add("MyVdir", 
                                           "IIsWebVirtualDir"))
  {
    virtualDirectory.Properties["Path"][0] = PATH_TO_MY_STUFF;
    virtualDirectory.Properties["AccessRead"][0] = true;
    virtualDirectory.Properties["AccessScript"][0] = 512;
    virtualDirectory.CommitChanges();
  }
}

如果您确实在 IIS6 中设置了 AppIsolated,它会被忽略,因为要使目录成为应用程序,您还需要设置 AppRoot。

IIS7 - IIS6 兼容性垫片

在 IIS7 中使用 System.DirectoryServices 时,您正在使用底层 II6 兼容性 API,它将这些 ADSI 调用转换为对新 IIS7 API 的调用。它并不完美,我怀疑当它看到 AppIsolated 被设置时,它假设你想要一个应用程序,尽管你没有指定任何其他与应用程序相关的元数据库值。

IIS7 托管 API 更好

您可能知道这一点,但最好通过托管的Microsoft.Web.Administration 位使用 IIS7 配置。并非所有 ADSI/元数据库兼容性设置在 IIS7 中都有等效设置,这可能会迫使转换层做出妥协以解决此问题。我在here 和here 的回答中提到了这些类型的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 2013-02-19
    • 2015-11-24
    • 1970-01-01
    • 2016-10-06
    相关资源
    最近更新 更多