Вопрос:

Виртуальный каталог внутри приложения ASP.NET Core в IIS

iis asp.net-core virtual-directory

12389 просмотра

6 ответа

1633 Репутация автора

У нас есть приложение, использующее ASP.NET Core 1.0 RC1 и размещенное на IIS. Работает нормально. Теперь у нас есть статический контент, который доступен в общей папке и должен быть доступен из приложения.

До ASP.NET 5 мы добавляли виртуальный каталог в IIS и могли легко получать доступ к общему контенту. С нашим размещенным приложением ASP.NET 5 это, к сожалению, не работает. Мы просто получаем 404ответ при попытке получить доступ к статическому контенту.

Наше приложение использует app.UseIISPlatformHandler()и app.UseStaticFiles(), но это не работает. Мы обнаружили, что можем использовать app.UseFileServer()с custom FileServerOptionsдля получения желаемого поведения, но нам любопытно, возможно ли это и с обычным «старым» способом добавления виртуального каталога в IIS.

Автор: Matthias Источник Размещён: 16.03.2016 08:17

Ответы (6)


4 плюса

47125 Репутация автора

Не напрямую.

Видите ли, проблема в том, что когда у вас есть приложение .NET-Core, оно запускается в Kestrell, а не в IIS (для .NET Core <2.2).

Теперь, чтобы разместить ваше приложение .NET-Core в IIS, AspNetCoreModule запускает ваше приложение .NET-Core с Kestrell на порту X 127.0.0.1, а затем перенаправляет трафик с вашего виртуального каталога iis-domain + на порт X на 127.0.0.1 (он может использовать что-то еще, кроме TCP).

Проблема 1 в том, что Kestrell имеет довольно ограниченную функциональность, то есть не имеет виртуальных каталогов.
Проблема 2 в том, что IIS, в отличие от nginx, на самом деле не выполняет обратное проксирование должным образом, или мы должны сказать «полностью».

IIS может пересылать domainxy: 80 на 127.0.0.1:random в порядке. Но что он не делает должным образом, так это переписывает domainxy: 80 / foo в 127.0.0.1:random (images, header, json-ajax-results, urls, return-url, cookies и т. Д. И наоборот). Вместо этого он переписывает домен: 80 / foo в 127.0.0.1:random/foo, что является проблемой, если сервер 127.0.0.1:random (Kestrell) не поддерживает виртуальные каталоги.

Поэтому, если вы хотите запустить свое приложение в своем виртуальном каталоге, у вас есть два варианта (оба включают изменение «вашего» приложения - если вы можете это сделать):
1) Поместите все свои вещи в каталог «foo» (включая контроллер MVC). маршрут), если ваше приложение будет развернуто только один раз.

2) Как предложено в https://github.com/aspnet/Hosting/issues/416#issuecomment-149046552, вы можете настроить каркас приложения для имитации этой папки, как в RoR:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    string virtual_directory = "/Virt_DIR";
    // virtual_directory = "/";

    if (virtual_directory.EndsWith("/"))
        virtual_directory = virtual_directory.Substring(0, virtual_directory.Length - 1);

    if (string.IsNullOrWhiteSpace(virtual_directory))
        Configure1(app, env, loggerFactory); // Don't map if you don't have to 
        // (wonder what the framework does or does not  do for that case)
    else 
        app.Map(virtual_directory, delegate(IApplicationBuilder mappedApp) 
            {
                Configure1(mappedApp, env, loggerFactory);
            }
        );
}

// Configure is called after ConfigureServices is called.
public void Configure1(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
       [...]  (here comes what used to be in your old Configure method)

Вам нужно будет где-то настроить имя виртуального каталога. Осторожно, когда у вас есть / возвращаются URL-адреса в JavaScript / ajax-запросах, они не будут автоматически отображаться. Вы должны сделать это сами, но так было и со старым ASP.NET.

Действительно, как RoR:

карта Rails.application.config.relative_url_root || "/"
    выполнить RedmineApp ::
Конец приложения

Что касается виртуального каталога в приложении: нет, это не так просто.
IIS - это полноценный веб-сервер, который будет обслуживать содержимое этого сопоставленного каталога так, как он был там (если он может читать содержимое).

Если вы перенаправите весь родительский каталог в Kestrell, то IIS не сможет обслуживать подкаталог, и ваше приложение должно будет это сделать. Это означает, что вам нужно настроить статический файловый сервер для этого конкретного каталога и сообщить ему, где находятся файлы, как вы это сделали.

То, что вы могли бы сделать, это сказать IIS не использовать прокси для этого конкретного виртуального подкаталога (так же, как вы можете определить местоположение статического файла в nginx - за исключением того, что IIS, вероятно, не поддерживает эту функцию).

Тем не менее, вы можете создать символическую ссылку в каталоге вашего приложения, которая идет в сетевую папку, если Windows способна на это (mklink). Тогда .NET Core сможет обслуживать его статически. Но на самом деле, это звучит как взломать.

Если вы не можете настроить IIS, вам действительно следует использовать app.UseFileServer () и определить местоположение документа в базе данных. Таким образом, вы можете просто удалить и повторно вставить приложение позже.

Автор: Stefan Steiger Размещён: 17.03.2017 09:54

0 плюса

1 Репутация автора

Мое решение использует path="/"вместо path="*"на web.configфайл

Автор: Nicolas Battaglia Размещён: 12.09.2017 04:10

16 плюса

3629 Репутация автора

Я столкнулся с этой проблемой сегодня, и, наконец, удалось ее исправить. Хитрость (для меня, вероятно, не для всех) состоит в том, чтобы убедиться, что aspNetCoreобработчик отключен в субприложении и включен в основном (ASP.NET Core) приложении.

В моем приложении ASP.NET Core есть базовый файл Web.config.

<configuration>
  <system.webServer>
    <handlers>
        <add name="aspNetCore" path="*" verb="*" type="" modules="AspNetCoreModule" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\bin\Debug\netcoreapp2.0\myapp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
</configuration>

и приложение, добавленное в качестве дополнительного приложения в IIS, имеет

<configuration>
  <!-- removed -->
  <system.webServer>
      <handlers>
          <remove name="aspNetCore" />
       </handlers>
  </system.webServer>
</configuration>
Автор: PerfectlyNormal Размещён: 17.10.2017 12:03

1 плюс

504 Репутация автора

Я знаю его вопрос с 1,8 года, но если кому-то нужно решить ту же проблему, попробуйте использовать это:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(); // For the wwwroot folder

    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "images")),
        RequestPath = new PathString("/MyImages")
    });
}

Вполне возможно изменить параметры PhysicalFileProvider для любой локальной или общей папки, и с этим подать файл.

Делать это таким образом не рекомендуется. Но для изучения предложите, это приемлемо.

Модуль статического файла не обеспечивает проверки авторизации. Любые файлы, обслуживаемые им, в том числе под wwwroot, являются общедоступными. Чтобы обслуживать файлы на основе авторизации: храните их вне wwwroot и любого каталога, доступного для промежуточного программного обеспечения статических файлов, и обслуживайте их с помощью действия контроллера, возвращая FileResult, где применяется авторизация.

В документации Microsoft Asp.Net мы можем найти более полную информацию, чтобы помочь с этой проблемой.

Проверьте эту ссылку: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files

Автор: Rafael Размещён: 15.11.2017 05:44

11 плюса

157 Репутация автора

Я нашел блог, который, я думаю, был написан ОП.

В результате мы вовсе не используем виртуальный каталог в IIS, а сопоставляем ваш путь в Startup.cs с каталогом физического сервера. Я надеюсь, что OP не возражает против того, что я вставил блог ниже, но он помог мне, когда я впервые столкнулся с этой проблемой сегодня.

Источник: https://www.jauernig-it.de/asp-net-coreiis-serving-content-from-a-file-share/

Существуют ситуации, когда вы хотите предоставить статическое содержимое вашему приложению, которое не является его частью, например, потому что оно существует в общем файловом ресурсе. Контент веб-сайта, который управляется бизнес-подразделением, может быть таким примером использования. В ASP.NET до Core это не было проблемой в IIS: просто создайте виртуальный каталог на своем веб-сайте IIS и укажите его для общего файлового ресурса.

К сожалению, в ASP.NET Core этот подход больше не работает. Если вы добавляете виртуальный каталог в приложение ASP.NET Core в IIS, он не распознается и возвращается 404. Это из-за DNX / Kestrel, который работает под IIS (с использованием модуля HttpPlatformHandler) и к которому IIS только передает запросы. Kestrel ничего не знает о виртуальных каталогах из IIS. А поскольку основные приложения ASP.NET не зависят от IIS и могут также выполняться без него (например, с автономной работой Kestrel), это следует рассматривать как хорошую вещь.

Но теперь нам нужно другое решение для нашей проблемы… к счастью, ASP.NET Core предоставляет нам программный интерфейс для обслуживания файлов из любого места. Просто добавьте следующий код в ваш метод Startup.cs Configure ():

app.UseFileServer(new FileServerOptions
{
    FileProvider = new PhysicalFileProvider(@"\\server\path"),
    RequestPath = new PathString("/MyPath"),
    EnableDirectoryBrowsing = false
});

По сути, это добавляет файловый сервер к физическому пути к серверу, который затем доступен по определенному пути запроса, в данном случае с отключенным просмотром каталога. Вы также можете обслуживать по пути относительно вашего приложения, используя новый PhysicalFileProvider (env.WebRootPath + "\ path") (данный env имеет тип IHostingEnvironment в качестве параметра Configure ()). Вуаля, вот и все. Нет необходимости добавлять «виртуальный каталог» в IIS, этот материал устарел и ушел в прошлое. Для меня это хорошая вещь, потому что мы становимся более независимыми от всего IIS ...

Автор: pook Размещён: 22.11.2017 11:37

0 плюса

46 Репутация автора

Испытываете ту же / похожую проблему, используя ASP.NET CORE 2.1.

Пока веб-файлы хранились в папке / wwwroot /, я создавал ВИРТУАЛЬНУЮ КАТАЛОГ для этой папки в IIS и при просмотре просматривал папки и файлы правильно. Однако браузер (http) их не тянет.

Я решил свою проблему, создав виртуальную директорию вне корня.

РАБОТАЕТ ЭТОМ СПОСОБОМ:

ВЕБ-САЙТ

/ Wwwroot /

/ CSS /

/ JS /

/ Библиотека /

/ ВИРТУАЛЬ-ПАПКА /

НЕ РАБОТАЕТ ЭТОМ СПОСОБОМ:

ВЕБ-САЙТ

/ Wwwroot /

/ CSS /

/ JS /

/ Библиотека /

/ ВИРТУАЛЬ-ПАПКА /

Автор: happy297 Размещён: 13.06.2019 05:47
Вопросы из категории :
32x32