Способ сделать это - манипулировать коллекцией Site.Applications
, которая представляет собой сплющенное дерево всех приложений на вашем сайте.
Для этих примеров мы предположим сайт под названием «MySite», на котором содержимое находится на локальном жестком диске по адресу: d:\mysite\www
. Номер IIS сайта - 3
, и сайт находится в собственном пуле приложений, также называемом «MySite».
Мы также примем следующую структуру папок для сайта
Для начала, мы получим сайт, к которому мы хотим добавить приложение, будем использовать переменную site
повсюду:
// Get my site
Site site = serverManager.Sites.First(s => s.Id == 3);
Корневое приложение "/":
На каждом сайте есть «корневое» приложение. Если мы откроем applicationHost.config
, расположенный в %systemroot%\windows\system32\inetsrv\config
и найдем узел <site>
для нашего сайта, мы увидим следующее:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\mysite\www" />
</application>
</site>
Каждый <site>
содержит коллекцию <application>
. Всегда будет хотя бы одно приложение, которое определяет корневое приложение, /
.
Атрибут applicationPool
указывает, какой пул приложений использовать.
Обратите внимание, что существует единственный дочерний элемент: virtualDirectory
.
Каждый application
имеет дочернюю коллекцию virtualDirectory
элементов, и в этой коллекции обычно будет хотя бы один элемент.
Значение по умолчанию <virtualDirectory>
в корневом приложении говорит нам:
- это это корень (
path="/"
) и
- что он физически находится в файловой системе на
d:\MySite\www
(physicalPath="d:\MySite\www"
).
path
каждого virtualDirectory
относится к path
, указанному в родительском пути application
.
Добавление виртуального каталога:
Если бы мы хотели добавить виртуальный каталог к «корню сайта», сопоставленному где-то еще в файловой системе, мы бы сделали:
Application rootApp = site.Applications.First(a => a.Path == "/");
rootApp.VirtualDirectories.Add("/vdir_1", @"D:\MySite\other_content");
serverManager.CommitChanges();
Результирующая конфигурация выглядит так:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="D:\MySite\www" />
<virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
</application>
</site>
И мы видим это в IIS Manager:
Добавление виртуального каталога в существующий виртуальный каталог:
Если бы мы хотели добавить дочерний виртуальный каталог в vdir1
, мы бы сделали:
root.VirtualDirectories.Add("/vdir_1/sub_dir1", @"d:\MySite\more_content");
это приводит к:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="D:\MySite\www" />
<virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
<virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
</application>
</site>
IIS Manager:
При добавлении виртуальных каталогов необходимо учитывать несколько моментов:
- Как уже упоминалось, виртуальный
path
всегда относительно родительского приложения path
- Последняя часть виртуальной
path
например. /vdir_1
и .../sub_dir1
становится именем виртуального каталога
- Совершенно законно иметь несколько виртуальных каталогов, указывающих на одну и ту же физическую папку
- За исключением части имени пути виртуального каталога, все части пути должны существовать либо как физические пути, либо как виртуальные пути в корне сайта (
d:\MySite\www
). то есть path
должен иметь возможность накладывать то, что уже существует, иначе виртуальный каталог не будет виден в диспетчере IIS.
Что касается последнего пункта, например, у нас нет физической папки или виртуального каталога с именем /vdir_2
, но следующий код совершенно допустим:
root.VirtualDirectories.Add("/vdir_2/sub_dir1", @"d:\MySite\even_more_content");
Вы не увидите /vdir_2/sub_dir1
в диспетчере IIS, но это разрешено законом, и вы можете перейти к нему. Мы также можем видеть это в applicationHost.config
:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="D:\MySite\www" />
<virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
<virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
<virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
</application>
</site>
Конвертировать папку в приложение:
Если вы только что загрузили приложение ASP.NET в папку /app_1
на своем сайте и хотите превратить это в собственное приложение, мы сделаем следующее:
Application app = site.Applications.Add("/app_1", @"d:\MySite\www\app_1");
// set application pool, otherwise it'll run in DefaultAppPool
app.ApplicationPoolName = "MySite";
serverManager.CommitChanges();
В applicationHost.config
мы видим, что добавлен новый элемент <application>
:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="D:\MySite\www" />
<virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
<virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
<virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
</application>
<application path="/app_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
</application>
</site>
В IIS мы видим:
Это эквивалентно щелчку правой кнопкой мыши «Преобразовать в приложение».
Добавить приложение в существующее приложение:
Добавить приложение как дочернее к существующему приложению очень просто. Скажем, мы хотим сделать /app_1/sub_app_1
вложенным приложением /app_1
:
Мы бы просто сделали:
Application app =
site.Applications.Add("/app_1/sub_app_1", @"d:\mysite\www\app_1\sub_app_1");
app.ApplicationPoolName ="MySite";
Результирующая конфигурация будет выглядеть так:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="D:\MySite\www" />
<virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
<virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
<virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
</application>
<application path="/app_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
</application>
<application path="/app_1/sub_app_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\mysite\www\app_1\sub_app_1" />
</application>
</site>
В IIS:
Добавить виртуальный каталог в приложение:
Теперь, если мы хотим добавить виртуальный каталог в это приложение, мы сделаем:
Application app = site.Applications.First(a => a.Path == "/app_1");
app.VirtualDirectories.Add("/vdir_1", @"d:\MySite\other_content");
В applicationHost.config
мы видим, что добавлен новый элемент <virtualDirectory>
:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="D:\MySite\www" />
<virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
<virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
<virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
</application>
<application path="/app_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
<virtualDirectory path="/vdir_1" physicalPath="d:\MySite\other_content" />
</application>
</site>
В IIS мы видим:
Опять же важно отметить, что виртуальный путь /vdir1
всегда относительно пути содержащего приложения.
Преобразование существующего виртуального каталога в приложение:
Что если мы захотим преобразовать только что созданный виртуальный каталог (/app_1/vdir1
) в приложение? Нам нужно сделать это в два этапа:
// Get the application
Application app_1 = site.Applications.First(a => a.Path == "/app_1");
// Find the virtual directory
VirtualDirectory vdir_1 = app_1.VirtualDirectories.First(v => v.Path == "/vdir_1");
// Remove it from app_1
app_1.VirtualDirectories.Remove(vdir_1);
// Create our application
Application vdir_1_app = site.Applications.Add("/app_1/vdir_1", vdir_1.PhysicalPath);
// set application pool, otherwise it'll run in DefaultAppPool
vdir_1_app.ApplicationPoolName = "MySite";
serverManager.CommitChanges();
Результирующий applicationHost.config
выглядит так:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="D:\MySite\www" />
<virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
<virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
<virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
</application>
<application path="/app_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
</application>
<application path="/app_1/vdir_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\MySite\other_content" />
</application>
</site>
В IIS Manager мы видим:
Добавить приложение в существующий виртуальный каталог:
Что произойдет, если мы хотим добавить приложение в виртуальный каталог, как это работает? В этом примере мы добавим приложение в виртуальный каталог /vdir_1/sub_dir1
, который мы создали ранее.
Application app =
site.Applications.Add("/vdir_1/sub_dir1/app_2", @"d:\mysite\other_content");
app.ApplicationPoolName = "MySite";
serverManager.CommitChanges();
Результирующий конфиг выглядит так:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="D:\MySite\www" />
<virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
<virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
<virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
</application>
<application path="/app_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
</application>
<application path="/app_1/vdir_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\MySite\other_content" />
</application>
<application path="/vdir_1/sub_dir1/app_2" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\mysite\other_content" />
</application>
</site>
А в диспетчере IIS мы видим:
Преобразование существующей дочерней папки в приложение:
В качестве последнего примера мы хотим превратить /other_apps/sub_app_1
в приложение:
Наш код выглядит так:
Application app =
site.Applications.Add("/other_apps/sub_app_1", @"d:\mysite\other_content");
app.ApplicationPoolName="MySite";
serverManager.CommitChanges();
Результирующий конфиг:
<site name="MySite" id="3">
<application path="/" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="D:\MySite\www" />
<virtualDirectory path="/vdir_1" physicalPath="D:\MySite\other_content" />
<virtualDirectory path="/vdir_1/sub_dir1" physicalPath="D:\MySite\more_content" />
<virtualDirectory path="/vdir_2/sub_dir1" physicalPath="D:\MySite\even_more_content" />
</application>
<application path="/app_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\MySite\www\app_1" />
</application>
<application path="/app_1/vdir_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\MySite\other_content" />
</application>
<application path="/vdir_1/sub_dir1/app_2" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\mysite\other_content" />
</application>
<application path="/other_apps/sub_app_1" applicationPool="MySite">
<virtualDirectory path="/" physicalPath="d:\mysite\other_content" />
</application>
</site>
В диспетчере IIS:
Надеюсь, это поможет объяснить связь между сайтами, приложениями и виртуальными каталогами.