Aplica asp-append-version a més de fitxers estàtics a la carpeta wwwroot

Data de creació de la pàgina :

Medi ambient

Estudi Visual
  • Estudi Visual 2019
Nucli ASP.NET
  • 3.1 (Pàgina de la navalla, MVC)

Els fitxers estàtics situats fora de la carpeta wwwroot no reflecteixen asp-append-version

app.UseStaticFiles Especificant una crida addicional StaticFileOptions al mètode Els fitxers estàtics també es poden col·locar en carpetes diferents de wwwroot. No obstant això, per als fitxers estàtics col·locats fora de la carpeta wwwroot, les etiquetes d'enllaç i script asp-append-version Si definiu l'atribut, no s'afegirà informació de la versió a l'adreça URL.

Ho provaré. Els fitxers estan ordenats en les següents configuracions:

Startup.Configure mètode per publicar també la carpeta Àrees/Lloc1/Contingut.

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

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

S'ha afegit el codi següent index.cshtml al . asp-append-version S'afegeixen cadascuna d'elles.

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

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

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

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

Quan l'executeu, la imatge es mostra correctament.

No obstant això, si mireu l'HTML de la pàgina, podeu veure que la cadena només s'expandeix als fitxers col·locats a wwwroot.

Causes en què l'asp-append-version no es reflecteix

Depèn de la propietat que determini si es reflecteix la versió asp-append. env.WebRootFileProvider IFileProvider Per defecte, el wwwroot PhysicalFileProvider especificat està definit de manera que no es reflecteixi en altres carpetes.

Hi ha una classe IFileProvider que pot tenir més CompositeFileProvider d'un Pots empaquetar més d'un aquí PhysicalFileProvider i donar-lo a env.WebRootFileProvider . Només es pot passar un camí físic de carpeta a l'últim, StaticFileOptions.RequestPath No és possible especificar més d'un, així que no crec que sigui l'acció prevista.

* env.WebRootFileProvider es rep per Startup.Configure IWebHostEnvironment env mètode.

Hereta IFileProvider i crea les teves pròpies classes

ASP.NET fitxerProvider perquè no es pot suportar només amb característiques estàndard al nucli.

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

Com que és llarg, no explicaré els detalls, sinó que explicaré breument, En primer lloc, StaticFileOptions tindré tota la llista d'això que he creat en aquesta classe. Més tard posaré aquesta classe env.WebRootFileProvider en una propietat.

Quan un client accedeix a cada mètode, cerca el fitxer estàtic al StaticFileOptions qual heu accedit en funció de l'adreça URL. Retorna el StaticFileOptions camí relatiu al fitxer pegat i estàtic. FileProvider Si no s'encerta staticFileOptions, la configuració de wwwroot s'aplica retornant el FitxerProvider per defecte.

Si retorneu la informació correcta del fitxer per a cada asp-append-version operació, es reflectirà l'atribut.

Per cert, aquest codi pot ser a qualsevol lloc.

Aplica la teva pròpia classe (CompositeStaticFileOptionsProvider)

Startup.Configure Arreglem-ho de la següent manera: Com està escrit, no hi ha res a explicar. StaticFileOptions Només els resumeixo en una matriu.

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

Si l'executeu ara, podeu veure que l'atribut es reflecteix en fitxers estàtics asp-append-version col·locats en carpetes diferents de wwwroot.