تطبيق asp-append-الإصدار بالإضافة إلى الملفات الثابتة في المجلد wwwroot

تاريخ إنشاء الصفحة :

وسط

استوديو مرئي
  • استوديو مرئي 2019
ASP.NET كور
  • 3.1 (صفحة الحلاقة، MVC)

الملفات الثابتة الموضوعة خارج المجلد wwwroot لا تعكس asp-append-version

app.UseStaticFiles عن طريق تحديد استدعاء إضافي StaticFileOptions إلى الأسلوب يمكن أيضا وضع الملفات الثابتة في مجلدات أخرى غير wwwroot. ومع ذلك، بالنسبة للملفات الثابتة الموضوعة خارج المجلد wwwroot، الارتباط وعلامات البرنامج النصي asp-append-version لا يضيف تعيين السمة معلومات الإصدار إلى عنوان URL.

سأجربها يتم ترتيب الملفات في التكوينات التالية:

Startup.Configure الأسلوب لنشر مجلد المناطق/Site1/Content أيضا.

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

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

تمت index.cshtml إضافة التعليمات البرمجية التالية إلى . يتم إضافة كل asp-append-version منها.

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

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

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

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

عند تشغيله، يتم عرض الصورة بشكل صحيح.

ومع ذلك، إذا نظرتم إلى HTML من الصفحة، يمكنك أن ترى أن السلسلة يتم توسيع فقط إلى الملفات الموضوعة في wwwroot.

الأسباب عند عدم انعكاس إصدار ملحق asp

يعتمد ذلك على الخاصية التي تحدد ما إذا كان ينعكس إصدار env.WebRootFileProvider asp-append-. IFileProvider بشكل افتراضي، يتم تعيين wwwroot PhysicalFileProvider المحدد بحيث لا تنعكس في مجلدات أخرى.

هناك فئة IFileProvider يمكن أن يكون أكثر من CompositeFileProvider واحد يمكنك حزمة أكثر من واحد هنا PhysicalFileProvider وإعطائها إلى env.WebRootFileProvider . يمكن تمرير مسار مجلد فعلي فقط إلى الأخير، StaticFileOptions.RequestPath ولا يمكن تحديد أكثر من واحد، لذلك لا أعتقد أنه سيكون الإجراء المقصود.

* env.WebRootFileProvider يتم Startup.Configure تلقيها عن طريق IWebHostEnvironment env الطريقة.

وراثة IFileProvider وإنشاء الفئات الخاصة بك

ASP.NET الملفProvider لأنه لا يمكن أن تكون معتمدة من قبل الميزات القياسية في كور وحدها.

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

لأنه طويل، وأنا لن أشرح التفاصيل، ولكن لشرح بإيجاز، أولا، StaticFileOptions سيكون لدي كل القائمة التي صنعتها في هذا الصف. سأصنف هذا الصف env.WebRootFileProvider على عقار لاحقا

يتم استدعاء كل أسلوب عند الوصول إليه من قبل عميل، لذا ابحث عن StaticFileOptions الملف الثابت الذي قمت بالوصول إليه استنادا إلى عنوان URL. إرجاع StaticFileOptions المسار النسبي إلى الملف hit و FileProvider static. إذا لم يتم ضرب staticFileOptions، يتم تطبيق إعداد wwwroot عن طريق إرجاع FileProvider الافتراضي.

إرجاع معلومات الملف الصحيحة لكل عملية asp-append-version سوف تعكس السمة.

بالمناسبة، هذا الرمز يمكن أن يكون في أي مكان.

تطبيق الفئة الخاصة بك (CompositeStaticFileOptionsProvider)

Startup.Configure دعونا إصلاحه على النحو التالي: كما هو مكتوب ، لا يوجد شيء لشرحه. StaticFileOptions أنا فقط أوجزهم في مجموعة.

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

إذا قمت بتشغيله الآن، يمكنك مشاهدة أن السمة تنعكس في ملفات ثابتة asp-append-version وضعت في مجلدات أخرى غير wwwroot.