Anwenden der asp-append-Version zusätzlich zu statischen Dateien im Ordner wwwroot

Erstellungsdatum der Seite :

Umgebung

Visual Studio
  • Visual Studio 2019
ASP.NET Core
  • 3.1 (Razor-Seite, MVC)

Statische Dateien, die außerhalb des wwwroot-Ordners abgelegt werden, spiegeln nicht die Asp-Append-Version wider.

app.UseStaticFiles Durch Angeben eines zusätzlichen StaticFileOptions Aufrufs der Methode Statische Dateien können auch in anderen Ordnern als wwwroot abgelegt werden. Für statische Dateien, die außerhalb des Ordners wwwroot, Links und Skript-Tags abgelegt werden, asp-append-version Durch Festlegen des Attributs werden der URL keine Versionsinformationen hinzugefügt.

Ich werde es versuchen. Die Dateien sind in den folgenden Konfigurationen angeordnet:

Startup.Configure Methode, um auch den Ordner Areas/Site1/Content zu veröffentlichen.

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

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

Der folgende index.cshtml Code wurde zu hinzugefügt. Jeder asp-append-version wird hinzugefügt.

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

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

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

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

Wenn Sie es ausführen, wird das Bild korrekt angezeigt.

Wenn Sie sich jedoch den HTML-Code der Seite ansehen, können Sie sehen, dass die Zeichenfolge nur auf die in wwwroot abgelegten Dateien erweitert wird.

Ursachen, wenn asp-append-version nicht widergespiegelt wird

Es hängt von der Eigenschaft ab, die bestimmt, ob die asp-append-Version env.WebRootFileProvider IFileProvider widergespiegelt wird. Standardmäßig ist die angegebene wwwroot PhysicalFileProvider so eingestellt, dass sie nicht in anderen Ordnern widergespiegelt wird.

Es gibt eine Klasse, die mehr als eine Klasse IFileProvider haben kann CompositeFileProvider Sie können hier mehr als eine packen PhysicalFileProvider und an env.WebRootFileProvider geben. Nur ein physischer Ordnerpfad kann an den letzten übergeben werden, StaticFileOptions.RequestPath Es ist nicht möglich, mehr als eine zu spezifizieren, daher glaube ich nicht, dass es die beabsichtigte Aktion sein wird.

* env.WebRootFileProvider wird durch Methode Startup.Configure IWebHostEnvironment env empfangen.

IFileProvider erben und eigene Klassen erstellen

ASP.NET fileProvider, da es nicht von Standardfunktionen in Core allein unterstützt werden kann.

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

Da es lang ist, werde ich nicht die Details erklären, sondern kurz erklären: Zuerst StaticFileOptions habe ich alle Listen von denen, die ich in dieser Klasse erstellt habe. Ich sete diese Klasse env.WebRootFileProvider später auf eine Eigenschaft.

Jede Methode wird aufgerufen, wenn ein Client auf sie zugreift, also suchen Sie anhand der URL nach StaticFileOptions der statischen Datei, auf die Sie zugegriffen haben. Gibt den StaticFileOptions relativen Pfad zur Treffer- und statischen FileProvider Datei zurück. Wenn staticFileOptions nicht aktiviert wird, wird die einstellung wwwroot angewendet, indem der Standard-FileProvider zurückgegeben wird.

Die Rückgabe der richtigen Dateiinformationen für jeden Vorgang asp-append-version spiegelt das Attribut wider.

Übrigens kann dieser Code überall sein.

Anwenden einer eigenen Klasse (CompositeStaticFileOptionsProvider)

Startup.Configure Lassen Sie uns es wie folgt beheben: Wie geschrieben, gibt es nichts zu erklären. StaticFileOptions Ich resümiere sie nur in einem Array.

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();
  // 省略
}

Wenn Sie es jetzt ausführen, können Sie sehen, dass das Attribut in statischen Dateien widergespiegelt wird, asp-append-version die in anderen Ordnern als wwwroot abgelegt werden.