Lietot asp-pievienot versiju papildus statiskajiem failiem wwwroot mapē

Lapas izveides datums :

Vides

Vizuālā studija
  • Visual Studio 2019
ASP.NET kodols
  • 3.1 (Skuvekļa lapa, MVC)

Statiskie faili, kas novietoti ārpus wwwroot mapes, neatspoguļo asp-append versiju

app.UseStaticFiles Norādot papildu StaticFileOptions izsaukumu uz metodi Statiskos failus var ievietot arī citās mapēs, nevis wwwroot. Tomēr statiskajiem failiem, kas novietoti ārpus wwwroot mapes, saites un skripta tagi asp-append-version Iestatot atribūtu, vietrādim URL netiek pievienota informācija par versiju.

Es pamēģināšu. Faili ir sakārtoti šādās konfigurācijās:

Startup.Configure metodi, lai publicētu arī mapi Apgabali/Vietne1/Saturs.

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

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

Ir index.cshtml pievienots šāds kods. Katrs asp-append-version no tiem ir pievienots.

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

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

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

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

Palaižot to, attēls tiek parādīts pareizi.

Tomēr, ja paskatās uz lapas HTML, var redzēt, ka virkne tiek izvērsta tikai failos, kas ievietoti wwwroot.

Cēloņi, kad asp-pievienotā versija netiek atspoguļota

Tas ir atkarīgs no rekvizīta, kas nosaka, vai asp-pievienotā versija tiek env.WebRootFileProvider IFileProvider atspoguļota. Pēc noklusējuma norādītais wwwroot PhysicalFileProvider ir iestatīts tā, lai tas nebūtu atspoguļots citās mapēs.

Ir klase, IFileProvider kurā var būt CompositeFileProvider vairāki Jūs varat iepakot vairāk nekā vienu PhysicalFileProvider šeit un dot to env.WebRootFileProvider . Tikai fiziskās mapes ceļu var nodot pēdējam, StaticFileOptions.RequestPath Nav iespējams norādīt vairāk par vienu, tāpēc es nedomāju, ka tā būs paredzētā rīcība.

* env.WebRootFileProvider tiek Startup.Configure saņemts ar IWebHostEnvironment env metodi.

Pārmantojiet IFileProvider un izveidojiet savas klases

ASP.NET failuProvider, jo to nevar atbalstīt tikai Core standarta līdzekļi.

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

Tā kā tas ir garš, es nepaskaidrošu detaļas, bet īsumā paskaidrošu, StaticFileOptions Pirmkārt, man būs viss saraksts ar to, ko es izveidoju šajā klasē. Es vēlāk iestatīšu env.WebRootFileProvider šo klasi uz īpašumu.

Katra metode tiek izsaukta, kad piekļūst klients, tāpēc meklējiet, StaticFileOptions kuram statiskajam failam jūs piekļurāt, pamatojoties uz URL. Atgriež StaticFileOptions relatīvo ceļu uz trāpījumu un statisko FileProvider failu. Ja staticFileOptions nav hit, wwwroot iestatījums tiek lietots, atgriežot noklusējuma FileProvider.

Pareizas faila informācijas atgriešana katrai asp-append-version operācijai atspoguļos atribūtu.

Starp citu, šis kods var būt jebkur.

Lietojiet savu klasi (CompositeStaticFileOptionsProvider)

Startup.Configure Salabosim to šādi: Kā rakstīts, nav ko paskaidrot. StaticFileOptions Es tos apkopoju masīvā.

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

Ja to palaižat tūlīt, varat redzēt, ka atribūts tiek atspoguļots statiskos asp-append-version failos, kas atrodas mapēs, kas nav wwwroot.