web-dev-qa-db-ja.com

ASP.NET 4.5プロジェクトでwwwrootフォルダー(ASP.NET Coreスタイル)を使用する

新しいasp.net(asp.net 5\core 1.0)Webアプリのアプローチがとても気に入っています。wwwrootフォルダーがルートであり、そこにある静的ファイルのみが提供されます。

ルーティングまたは他の構成を介して、asp.net 4.5プロジェクトのwwwrootフォルダーが同様の方法で動作し、静的ファイルがそのファイルからのみ提供され、静的ファイルのWebアプリケーションの「ルート」になるようにすることはできますか?

(これを尋ねる動機の一部は、VS = 2015のasp.net 5プロジェクトでangularアプリがホストされていることですが、これをasp.net 4.5プロジェクトに移動する必要がありますが、ディスク上の既存の構造を保持したい)

OWINを使用してみる

空のASP.NET 4.5 WebアプリプロジェクトとOWINを使用してこれを試みました。したがって、私のフォルダー構造にはmy angular appがあり、メインのindex.htmlファイルがプロジェクトフォルダーのwwwrootフォルダーにあります。プロジェクトのルートにはHTMLファイルがありません。

Nugetと次の起動ファイルを使用してOWINを追加しました。

[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);
        }
    }
}

これは失敗しますが、これを実行するとindex.htmlファイルのソースがロードされますが、それが参照するすべてのcss、jsなどのファイルは404で失敗します。さらに悪いことに、ルートURLにgulpfile.jsを追加すると、プロジェクトフォルダのルートからgulpファイルをロードします。これはまさに私が避けようとしていることです。

何か案は?

25
mutex

私はこれを行うための作業方法を今持っていると思います。少しグーグルと実験をしましたが、最終的に私は次のプロセスを思いつきました:

  1. 空のテンプレートを選択して、VS2015で新しいASP.NET 4.5プロジェクトを作成します。

  2. 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. 以下をweb.configファイルに追加して、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>
    

私はこれを行う方法についてのより良い提案に常にオープンですが、これは少なくとも私にとってはうまくいくようです。

30
mutex

OWINはVS 2017で実行している開発環境で機能しましたが、Azureにデプロイすると機能しませんでした。 SPAも実行し、〜/ wwwroot /にwebpackの出力を保存していますが、.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>

最初のルールは、探しているファイルがルートに存在しないこと、フォルダーではないこと、is foundが新しいパスにあること、wwwrootフォルダーではないこと、またはその一部ではないことを確認しますAPIの。これらの条件がすべて満たされた場合、wwwrootからデータをロードしようとします。

2番目のルールは、API、またはルートに実際に存在するファイルをロードしようとしていないことを確認するためにチェックします。両方の条件が満たされている場合は、デフォルトのSPA HTMLドキュメントがロードされます(この場合は、reactを使用します)。

事実上、これにより、react-router 4は、上記の他のすべての条件が一致を検出できなかった後に他のすべてのルートを処理し、react-routerルートの1つをロードしようとしたときに404エラーをスローしないようにすることができます。

9
sec0ndHand

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>
_

/ apiでホストするWeb-apiの場合、^(wwwroot|api)/.*などのプレフィックスをURL正規表現に追加することもできます。

0
Andreas Ågren