Asp-lisaversiooni rakendamine lisaks staatilistele failidele kaustas wwwroot

Lehe loomise kuupäev :

Keskkond

Visuaalstuudio
  • Visuaalstuudio 2019
ASP.NET Tuum
  • 3.1 (Raseerija leht, MVC)

Väljaspool kausta wwwroot paigutatud staatilised failid ei kajasta asp-lisaversiooni

app.UseStaticFiles Määrates meetodile täiendava StaticFileOptions kõne Staatilisi faile saab paigutada ka muudesse kaustadesse peale wwwroot. Staatiliste failide puhul, mis on paigutatud väljapoole kausta wwwroot, lingi- ja skriptisildid asp-append-version Atribuudi seadmine ei lisa URL-ile versiooniteavet.

Ma proovin. Failid on paigutatud järgmistesse konfiguratsioonidesse:

Startup.Configure meetod ka kausta Alad/Sait1/Sisu avaldamiseks.

// wwwroot フォルダで静的ファイル参照を有効にする
app.UseStaticFiles();

// Site1 用の物理コンテンツフォルダと参照 URL を紐づける
app.UseStaticFiles(new StaticFileOptions()
{
  FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Areas/Site1/Content")),
  RequestPath = "/Site1",
});

Järgmine index.cshtml kood on lisatud . Kõik asp-append-version lisatakse.

<!-- ここから追加 -->

<!-- wwwroot のファイル -->
<img src="~/image/sample.png" asp-append-version="true" />

<!-- wwwroot 以外のファイル -->
<img src="~/site1/image/sample1.png" asp-append-version="true" />

<!-- ここからまで -->

Selle käivitamisel kuvatakse pilt õigesti.

Kui aga vaatate lehe HTML-i, näete, et stringi laiendatakse ainult faili wwwroot paigutatud failidele.

Põhjused, kui asp-lisa versioon ei kajastu

See sõltub atribuudist, mis määrab, kas asp-lisa versioon env.WebRootFileProvider IFileProvider peegeldub. Vaikimisi seatakse määratud wwwroot PhysicalFileProvider nii, et see ei kajastuks teistes kaustades.

On IFileProvider klass, kus võib olla rohkem kui CompositeFileProvider üks Võite siia pakkida rohkem kui ühe PhysicalFileProvider ja anda selle env.WebRootFileProvider . Ainult füüsilise kausta tee saab edastada viimasele, StaticFileOptions.RequestPath Ei ole võimalik täpsustada rohkem kui ühte, nii et ma ei arva, et see on kavandatud tegevus.

* env.WebRootFileProvider Startup.Configure võetakse vastu IWebHostEnvironment env meetodil.

Päri IFileProvider ja loo oma klassid

ASP.NET fileProvider, kuna seda ei saa toetada ainult Core'i standardfunktsioonid.

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Primitives;

namespace Microsoft.Extensions.FileProviders
{
  /// <summary>
  /// wwwroot フォルダ以外のファイルで "asp-append-version”を有効にするための複数の <see cref="StaticFileOptions"/> を管理するファイルプロバイダです。
  /// </summary>
  class CompositeStaticFileOptionsProvider : IFileProvider
  {
    private readonly IFileProvider _webRootFileProvider;
    private readonly IEnumerable<StaticFileOptions> _staticFileOptions;

    /// <summary>
    /// コンストラクタです。
    /// </summary>
    /// <param name="webRootFileProvider">
    /// デフォルトの wwwroot が設定されている WebRootFileProvider を指定します。通常は env.WebRootFileProvider を指定してください。
    /// これは追加した <see cref="StaticFileOptions"/> がヒットしなかった場合に使用するためです。
    /// </param>
    /// <param name="staticFileOptions">
    /// 追加した静的ファイルオプションの一覧です。
    /// FileProvider と RequestPath が設定されている必要があります。
    /// </param>
    public CompositeStaticFileOptionsProvider(IFileProvider webRootFileProvider, IEnumerable<StaticFileOptions> staticFileOptions)
    {
      _webRootFileProvider = webRootFileProvider ?? throw new ArgumentNullException(nameof(webRootFileProvider));
      _staticFileOptions = staticFileOptions;
    }

    /// <summary>
    /// 指定されたパスにあるディレクトリを列挙します(存在する場合)。
    /// </summary>
    /// <param name="subpath">ディレクトリを識別する相対パス。</param>
    /// <returns>ディレクトリの内容を返します。</returns>
    public IDirectoryContents GetDirectoryContents(string subpath)
    {
      var result = GetFileProvider(subpath);
      return result.FileProvider.GetDirectoryContents(result.StaticFileRelativePath);
    }

    /// <summary>
    /// 指定されたパスでファイルを見つけます。
    /// </summary>
    /// <param name="subpath">ファイルを識別する相対パス。</param>
    /// <returns>ファイル情報。 発信者はExistsプロパティを確認する必要があります。</returns>
    public IFileInfo GetFileInfo(string subpath)
    {
      var result = GetFileProvider(subpath);
      return result.FileProvider.GetFileInfo(result.StaticFileRelativePath);
    }

    /// <summary>
    /// 指定されたフィルターの Microsoft.Extensions.Primitives.IChangeToken を作成します。
    /// </summary>
    /// <param name="filter">監視するファイルまたはフォルダーを決定するために使用されるフィルター文字列。 例:**/*.cs、*.*、subFolder/**/*.cshtml。</param>
    /// <returns>ファイル一致フィルターが追加、変更、または削除されたときに通知される Microsoft.Extensions.Primitives.IChangeToken。</returns>
    public IChangeToken Watch(string filter)
    {
      var result = GetFileProvider(filter);
      return result.FileProvider.Watch(result.StaticFileRelativePath);
    }

    /// <summary>
    /// 指定された相対 URL に含まれる <see cref="StaticFileOptions"/> を探し、その FileProvider と静的ファイルへの相対パスを返します。
    /// 見つからなかった場合は wwwroot を持つ FileProvider を返します。
    /// </summary>
    /// <param name="path">アクセスされたホスト名以降の相対 URL。</param>
    /// <returns>検索された <see cref="StaticFileOptions"/> の FileProvider と RequestPath から静的ファイルへの相対パス。</returns>
    private (IFileProvider FileProvider, string StaticFileRelativePath) GetFileProvider(string path)
    {
      if (_staticFileOptions != null)
      {
        foreach (var option in _staticFileOptions)
        {
          // 登録している RequestPath とアクセスされた URL の大文字小文字が異なる場合があるので OrdinalIgnoreCase を指定
          if (path.StartsWith(option.RequestPath, StringComparison.OrdinalIgnoreCase))
          {
            return (option.FileProvider, path[option.RequestPath.Value.Length..]);
          }
        }
      }
      return (_webRootFileProvider, path);
    }
  }
}

Kuna see on pikk, ei selgita ma üksikasju, vaid selgitan lühidalt, Esiteks StaticFileOptions on mul nimekiri sellest, mille ma selles klassis lõin. Ma panen selle klassi env.WebRootFileProvider hiljem kinnistule.

Iga meetod kutsutakse, kui klient pääseb juurde, nii et otsige, StaticFileOptions millist staatilist faili te URL-i põhjal kasutasite. Tagastab StaticFileOptions tabamuse ja staatilise faili suhtelise FileProvider tee. Kui staatilisi FileOptions ei tabata, rakendatakse wwwroot säte, tagastades vaikimisi FileProvider.

Iga toimingu õige failiteabe tagastamine asp-append-version kajastab atribuuti.

Muide, see kood võib olla kus iganes.

Rakenda oma klass (CompositeStaticFileOptionsProvider)

Startup.Configure Parandame selle järgmiselt: Nagu kirjutatud, pole midagi selgitada. StaticFileOptions Ma lihtsalt võtan need massiivis kokku.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  // 省略
  app.UseHttpsRedirection();
  
  // ここから修正
  
  var staticOptions = new StaticFileOptions[]
  {
    // Site1 用の物理コンテンツフォルダと参照 URL を紐づける
    new StaticFileOptions()
    {
      FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Areas/Site1/Content")),
      RequestPath = "/Site1",
    },
    // 複数ある場合はこんな感じで追加
    //new StaticFileOptions()
    //{
    //  FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Areas/Site2/Content")),
    //  RequestPath = "/Site2",
    //},
  };
  
  // wwwroot フォルダで静的ファイル参照を有効にする
  app.UseStaticFiles();
  
  // 追加したい StaticFileOptions
  foreach (var option in staticOptions)
  {
    app.UseStaticFiles(option);
  }
  
  // StaticFileOptions を独自クラスでまとめて WebRootFileProvider にセットする
  var compositeProvider = new CompositeStaticFileOptionsProvider(env.WebRootFileProvider, staticOptions);
  env.WebRootFileProvider = compositeProvider;
  
  // ここまで修正
  
  app.UseRouting();
  // 省略
}

Kui käivitate selle kohe, näete, et atribuut peegeldub asp-append-version staatilistes failides, mis on paigutatud muudesse kaustadesse kui wwwroot.