web-dev-qa-db-ja.com

IISのASP.NET Coreアプリ内の仮想ディレクトリ

ASP.NET Core 1.0 RC1を使用し、IISでホストされるアプリケーションがあります。正常に動作します。これで静的コンテンツが作成されました。これはファイル共有で利用でき、アプリケーションからアクセスできるはずです。

ASP.NET 5の前に、IISに仮想ディレクトリを追加し、共有コンテンツに簡単にアクセスできました。ホストされたASP.NET 5アプリケーションでは、残念ながらこれは機能していないようです。静的コンテンツにアクセスしようとしたときに_404_を取得します。

私たちのアプリケーションはapp.UseIISPlatformHandler()app.UseStaticFiles()を使用していますが、これは機能しません。カスタムFileServerOptionsapp.UseFileServer()を使用して目的の動作を得ることができることを発見しましたが、IISに仮想ディレクトリを追加する通常の「古い」方法でも可能かどうか興味があります。

17
Matthias

今日この問題に遭遇し、ようやく修正することができました。トリック(私にとっては、おそらく全員のためではない)は、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>
16
PerfectlyNormal

OPが書いたに違いないと思うブログを見つけました。

最終的には、IISで仮想ディレクトリを使用するのではなく、Startup.csのパスを物理サーバーディレクトリにマップします。OPがブログを貼り付けたことを気にしないでください。以下ですが、今日この問題に最初に出会ったときに役立ちました。

ソース: https://www.jauernig-it.de/asp-net-coreiis-serving-content-from-a-file-share/

アプリケーションで静的コンテンツを提供したい場合、それはその一部ではありません。共通のファイル共有に存在するためです。事業部が管理するWebサイトのコンテンツは、このようなユースケースになる可能性があります。 Core以前のASP.NETでは、これはIISでは問題ありませんでした。IIS Webサイト内に仮想ディレクトリを作成し、ファイル共有をポイントするだけです。

残念ながら、ASP.NET Coreでは、このアプローチはもう機能していません。 IISのASP.NET Coreアプリケーションに仮想ディレクトリを追加すると、認識されず、404が返されます。これは、IIS(HttpPlatformHandlerモジュールを使用)の下で実行されているDNX/Kestrelと、IISがリクエストを仲介するだけです。Kestrelが知らないためです。また、ASP.NET Coreアプリケーションは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はConfigure()のパラメーターとしてIHostingEnvironmentタイプです)。出来上がり、それだけです。 IISに「仮想ディレクトリ」を追加する必要はありません。これは非推奨であり、過去のものです。私にとって、これは良いことです。なぜなら、私たちはIIS全体からより独立するからです…

13
pook

直接ではありません。

ご覧のとおり、問題は、.NET-Coreアプリケーションがある場合、アプリケーションはIIS(.NET Core <2.2の場合)ではなくKestrellで実行されることです。

次に、IISで.NET-Coreアプリケーションをホストするために、AspNetCoreModuleは127.0.0.1のポートXでKestrellを使用して.NET-Coreアプリケーションを起動し、iis-domain + virtualディレクトリからポートXへのトラフィックを逆プロキシします127.0.0.1(TCP以外のものを使用する場合があります)。

問題1は、Kestrellの機能がかなり制限されているため、仮想ディレクトリがないことです。
問題2は、IISはnginxとは異なり、実際にリバースプロキシを適切に実行しないか、または「完全に」言う必要があります。

IISはdomainxy:80を127.0.0.1:ランダムに転送できます。しかし、それが正しく行わないのは、domainxy:80/fooを127.0.0.1:randomに書き換えることです(画像、ヘッダー、json-ajax-results、urls、return-urls、cookieなど、およびその逆)。代わりに、domain:80/fooを127.0.0.1:random/fooに書き換えます。これは、127.0.0.1:random(Kestrell)上のサーバーが仮想ディレクトリをサポートしていない場合に問題になります。

そのため、仮想ディレクトリでアプリケーションを実行する場合、2つのオプションがあります(両方とも「あなたの」アプリケーションを変更する必要があります-できる場合)。
1)アプリケーションを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)

仮想ディレクトリの名前をどこかに設定する必要があります。 JavaScript/ajax-requestsでURLを持っている/返すときに注意してください。URLは自動的にマッピングされません。これは自分で行う必要がありますが、以前のASP.NETでもこの方法でした。

本当に、RoRのように:

map Rails.application.config.relative_url_root || "/" 行う
RedmineApp :: Applicationを実行します
終わり

アプリケーション内の仮想ディレクトリに関して:いいえ、これはそれほど単純ではありません。
IISは完全なWebサーバーであり、マップされたディレクトリのコンテンツをそこにあったように提供します(コンテンツを読み取ることができる場合)。

親ディレクトリ全体をKestrellに転送すると、IISはサブディレクトリを提供できず、アプリケーションはそれを行う必要があります。つまり、静的ファイルを設定する必要がありますその特定のディレクトリのサーバー、およびあなたが行ったように、ファイルがある場所を教えてください。

あなたができるかもしれないことは、特定の仮想サブディレクトリをプロキシしないようにIIS(nginxで静的ファイルの場所を定義できるように-IISはおそらくその機能をサポートしていません。

ただし、Windowsがネットワークフォルダー(mklink)に対応している場合は、ネットワークフォルダーに移動するシンボリックリンク(またはマウント/ジャンクション)をアプリケーションディレクトリ内に作成できます。その後、.NET Coreは静的にサービスを提供できるはずです。しかし、実際には、それはハックのように聞こえます。

IISを構成できない場合は、実際にapp.UseFileServer()を使用して、データベース内のドキュメントの場所を定義する必要があります。そうすれば、後でアプリケーションを削除して再挿入できます。

4
Stefan Steiger

私は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

1
Rafael

私の解決策はpath="/" の代わりに path="*" オン web.configファイル

0