Asp-append-versie toepassen naast statische bestanden in de map wwwroot

Aanmaakdatum van pagina :

Milieu

Visuele studio
  • Visuele Studio 2019
ASP.NET Kern
  • 3.1 (De pagina van het scheermes, MVC)

Statische bestanden die buiten de wwwroot-map worden geplaatst, weerspiegelen geen asp-append-versie

app.UseStaticFiles Door een extra StaticFileOptions aanroep van de methode op te geven Statische bestanden kunnen ook in andere mappen dan wwwroot worden geplaatst. Voor statische bestanden die buiten de wwwroot-map, koppelings- en scripttags zijn geplaatst asp-append-version Als u het kenmerk instelt, worden er geen versiegegevens aan de URL toegevoegd.

Ik zal het eens proberen. De bestanden zijn gerangschikt in de volgende configuraties:

Startup.Configure methode om ook de map Areas/Site1/Content te publiceren.

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

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

De volgende index.cshtml code is toegevoegd aan . Elk asp-append-version wordt toegevoegd.

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

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

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

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

Wanneer u deze uitvoert, wordt de afbeelding correct weergegeven.

Als u echter naar de HTML van de pagina kijkt, kunt u zien dat de tekenreeks alleen wordt uitgebreid naar de bestanden die in wwwroot zijn geplaatst.

Oorzaken wanneer asp-append-version niet wordt weergegeven

Het hangt af van de eigenschap die bepaalt of de asp-append-versie env.WebRootFileProvider wordt IFileProvider weergegeven. Standaard is de opgegeven wwwroot PhysicalFileProvider zo ingesteld dat deze niet wordt weergegeven in andere mappen.

Er is een klasse IFileProvider die meer dan één kan hebben CompositeFileProvider Je kunt er hier meer dan één inpakken PhysicalFileProvider en het env.WebRootFileProvider aan. Alleen een fysiek mappad kan worden doorgegeven aan de laatste, StaticFileOptions.RequestPath Het is niet mogelijk om er meer dan één te specificeren, dus ik denk niet dat het de beoogde actie zal zijn.

* env.WebRootFileProvider wordt per methode Startup.Configure IWebHostEnvironment env ontvangen.

IFileProvider overnemen en uw eigen klassen maken

ASP.NET fileProvider omdat het niet alleen kan worden ondersteund door standaardfuncties in Core.

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

Omdat het lang is, zal ik de details niet uitleggen, maar kort uitleggen, Eerst StaticFileOptions heb ik alle lijst die ik in deze klas heb gemaakt. Ik zet deze les later op env.WebRootFileProvider een woning.

Elke methode wordt aangeroepen wanneer deze wordt geopend door een client, dus zoek naar StaticFileOptions welk statisch bestand u hebt geopend op basis van de URL. Retourneert het StaticFileOptions relatieve pad naar het hit- en statische FileProvider bestand. Als staticFileOptions niet wordt geraakt, wordt de wwwroot-instelling toegepast door de standaard FileProvider te retourneren.

Als u de juiste bestandsinformatie voor elke bewerking asp-append-version retourneert, wordt het kenmerk weergegeven.

Trouwens, deze code kan overal zijn.

Uw eigen klasse toepassen (CompositeStaticFileOptionsProvider)

Startup.Configure Laten we het als volgt oplossen: Zoals geschreven, is er niets uit te leggen. StaticFileOptions Ik vat ze samen in een 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();
  // 省略
}

Als u het nu uitvoert, kunt u zien dat het kenmerk wordt weerspiegeld in statische bestanden asp-append-version die in andere mappen dan wwwroot zijn geplaatst.