Использование папки wwwroot (ASP.NET 5 стиль) в ASP.NET 4.5 проект

Мне очень нравится подход нового asp.net (asp.net 5core 1.0) веб-приложения с папкой wwwroot, являющейся корневым и только статическими файлами, обслуживаемыми там.

возможно через маршрутизацию или другую конфигурацию иметь папку wwwroot в asp.net 4.5 проект ведет себя аналогичным образом, так что статические файлы подаются только из него, и это "корень" webapp для статических файлов?

(часть моей мотивации в этом вопросе заключается в том, что у меня есть приложение angular размещено в asp.net 5 проект в VS2015, но мне нужно переместить это в asp.net 4.5 проект, но хотелось бы сохранить существующую структуру на диске)

попытка использовать OWIN

Я попытался это сделать с помощью пустого ASP.NET 4.5 проект веб-приложения и OWIN. Таким образом, моя структура папок имеет мое угловое приложение с основным индексом.html-файл в папке wwwroot в папке проекта. В корне проекта нет HTML-файлов.

Я добавил OWIN через nuget и следующий загрузочный файл:

[assembly: OwinStartup(typeof(MyApp.UI.Startup))]
namespace MyApp.UI
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            string root = AppDomain.CurrentDomain.BaseDirectory;
            var physicalFileSystem = new PhysicalFileSystem(Path.Combine(root, "wwwroot"));
            var options = new FileServerOptions
            {
                EnableDefaultFiles = true,
                FileSystem = physicalFileSystem
            };
            options.StaticFileOptions.FileSystem = physicalFileSystem;
            options.StaticFileOptions.ServeUnknownFileTypes = false;
            options.DefaultFilesOptions.DefaultFileNames = new[] {"index.html"};
            app.UseFileServer(options);
        }
    }
}

это не удается, хотя-источник моего индекса.html-файл загружается, когда я запускаю это, но все css, JS и т. д. Файлы, на которые он ссылается, терпят неудачу с 404. Еще хуже, если я добавлю gulpfile.js на корневой url-адрес загружает мой файл gulp из корневой папки проекта. Именно этого я и пытаюсь избежать.

какие идеи?

3 ответов


Я считаю, что у меня есть рабочий метод для делать это сейчас. Взял немного гуглить и экспериментировать, но в конце концов я придумал следующий процесс:

  1. создать новый ASP.NET 4.5 проект в VS2015, выбрав пустой шаблон

  2. добавить ссылки OWIN через nuget (Install-Package Microsoft.Owin.Host.SystemWeb и Microsoft.Owin.StaticFiles)

  3. добавьте файл запуска, подобный этому:

    [assembly: OwinStartup(typeof(MyApp.Startup))] namespace MyApp.UI { public class Startup { public void Configuration(IAppBuilder app) { string root = AppDomain.CurrentDomain.BaseDirectory; var physicalFileSystem = new PhysicalFileSystem(Path.Combine(root, "wwwroot")); var options = new FileServerOptions { RequestPath = PathString.Empty, EnableDefaultFiles = true, FileSystem = physicalFileSystem }; options.StaticFileOptions.FileSystem = physicalFileSystem; options.StaticFileOptions.ServeUnknownFileTypes = false; app.UseFileServer(options); } } }

  4. добавить следующие веб.файл конфигурации, чтобы предотвратить IIS от обслуживания статических файлов, которые вы не хотите, и заставить все через конвейер OWIN:

    <system.webServer> <handlers> <remove name="StaticFile"/> <add name="Owin" verb="" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb"/> </handlers> </system.webServer>

Я всегда открыт для лучших предложений о том, как это сделать, но это, по крайней мере, работает для меня.


хотя OWIN работал для меня в моей среде разработки, запущенной в VS 2017, он не работал после развертывания в azure. Мы также запускаем SPA и сохраняем вывод webpack в ~/wwwroot/, но хотим, чтобы он загружался, как если бы он был в корне проекта ~/ так же, как это делает .net core webapi. Я выполнил это, используя только перезапись URL, показанную ниже:

<system.webServer>
<rewrite>
  <rules>
    <rule name="wwwRootFix" stopProcessing="true">
      <match url="(.*)" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        <add input="{APPL_PHYSICAL_PATH}wwwroot\{R:1}" matchType="IsFile" />
        <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
        <add input="{REQUEST_URI}" pattern="^/(wwwroot)" negate="true" />
      </conditions>
      <action type="Redirect" url="/wwwroot/{R:1}" />
    </rule>
    <rule name="React Routes" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
        <add input="{REQUEST_URI}" pattern="^/(wwwroot)" negate="true" />
      </conditions>
      <action type="Rewrite" url="/wwwroot/index.html" />
    </rule>
  </rules>
</rewrite>
</system.webServer>

первое правило гарантирует, что файл, который вы ищете, не существует в корень, не в папку нашел в новом пути это не папка wwwroot и не является частью api. Если все эти условия выполнены, он пытается загрузить данные из wwwroot.

второе правило проверяет, не пытаетесь ли вы загрузить api или файл, который фактически существует в корне. Если оба условия выполнены, он загружает HTML-документ SPA по умолчанию (в нашем случае мы используем react).

эффективно это позволяет react-router 4 обрабатывать все другие маршруты после всех других условий выше не удалось найти совпадение и сделать так, чтобы он не выдавал ошибку 404 при попытке загрузить один из маршрутов react-router.


Если вы хотите использовать IIS для этого вы можете создать правило перезаписи:

<system.webServer>
    <rewrite>
      <rules>
        <rule name="RewriteUnknownToIndex" patternSyntax="ECMAScript" stopProcessing="true">
          <match url="^wwwroot/.*" negate="true" />
          <action type="Rewrite" url="/wwwroot/index.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

вы также можете добавить префикс в регулярное выражение url, например ^(wwwroot|api)/.*, если это веб-api, который вы хотели бы разместить в /api.