只有累積,沒有奇蹟

2020年7月1日 星期三

[NETCore] ASP.NET Core 靜態檔案設定 - UseStaticFiles

前言
在過去開發 .NET Framework 時代在專案使用靜態檔案是一塊小蛋糕,只需要在專案指定 Folder 加入需要的靜態檔案內容即可,像是圖片就放在 image、javascript 內容就放在 js 資料底下...等等,但同樣事情在 ASP.NET Core 專案可就完全不同,在 .NET Core 專案中是無法直接瀏覽靜態檔案的,需要透過一些設定方式才可以在專案看到像是 HTML、CSS、Image 或是 javascript 靜態檔案,這篇文章就是簡單說明在 ASP.NET Core 專案中如何設定才可以看到靜態檔案內容,若有問題歡迎提出一起討論或是給予指導。

靜態檔案
在 ASP.NET Core 中 Web 檔案會存放在專案根目錄中,預設存放位置是專案根目錄  project / wwwroot  底下,其資料夾底下可以存放多個資料夾如下,如果要存取 image 子資料夾底下的 test.jpg,其 URL 格式為 http:// yourApplicaitonName:9487/image/test.jpg
以下就透過簡單的範例,在 ASP.NET Core 專案簡單示範如何加上靜態檔案
簡單來說兩個步驟可以完成
  1. 加入靜態實體檔案
  2. 加入 UseStaticFiles 方法
Step 1 : 前面提到預設靜態檔案目錄是 wwwroot,在 wwwroot 目錄底下新增一個 helloworrld.html 檔案
其 html 內容就簡單輸入 Hello World ASP.NET Core !!!
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <title></title>
  6. </head>
  7. <body>
  8. Hello World ! ASP.NET Core
  9. </body>
  10. </html>
Step 2 : 在 Startup 中 Configure 新增  UseStaticFiles  方法,UseStaticFile 是  IApplicationBuilder  的擴充方法,主要是啟用靜態文件服務,背後其實是呼叫另一個 middleware 幫妳進行靜態檔案的設定
  1. app.UseStaticFiles();
好的,經過設定完畢之後在開啟網站並在網頁 url 後面加上 helloworld.html,即可在網頁上看到 Hello world ! ASP.NET Core 字眼,新增成功 !!
未設定 UseStaticFiles
如果未設定 UseStaticFiles 或是未將檔案放置在預設路徑底下,則會出現 Http Error 404 not found 錯誤畫面,如下圖所示
透過以上步驟,就可以輕鬆解決在 ASP.NET Core 無法顯示靜態檔案問題,讓靜態檔案找到回家的路(咦

UseStaticFiles 
為何透過 UseStaticFiles 方法就可以啟用靜態檔案呢? 接下來我們在往下追看看方法做了什麼事情以及實作細節,在  UseStaticFiles  方法提供三種多載情境給開發者使用,三種方法分別是
  • 預設路徑 : 無任何參數
  • 指定靜態檔案路徑 : requestPath
  • 指定 StaticFileOptions 物件
UseStaticFiles
無參數的方法如下
  1. /// <summary>
  2. /// Enables static file serving for the current request path
  3. /// </summary>
  4. /// <param name="app"></param>
  5. /// <returns></returns>
  6. public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app)
  7. {
  8. if (app == null)
  9. throw new ArgumentNullException(nameof (app));
  10. return app.UseMiddleware<StaticFileMiddleware>(Array.Empty<object>());
  11. }
從上述代碼可以看到,無參數的方法主要是透過設定  StaticFileMiddleware  來做靜態檔案的設定,在其 middleware invoke 方法中主要是處理已知靜態檔案 Request 請求,也就是確認 MIME 的 Content Type 是可以被識別的才會處理其靜態檔案請求內容,路徑則是透過預設的 wwwroot 路徑位置來讀取檔案位置,

UseStaticFiles 指定靜態檔案路徑
此方法是指定檔案路徑位置作為參數,接著再透過 UseStaticFiles  指定其 StaticFileOptions 作為參數,相關代碼如下
  1. /// <summary>
  2. /// Enables static file serving for the given request path
  3. /// </summary>
  4. /// <param name="app"></param>
  5. /// <param name="requestPath">The relative request path.</param>
  6. /// <returns></returns>
  7. public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app, string requestPath)
  8. {
  9. if (app == null)
  10. throw new ArgumentNullException(nameof (app));
  11. IApplicationBuilder app1 = app;
  12. StaticFileOptions options = new StaticFileOptions();
  13. options.RequestPath = new PathString(requestPath);
  14. return app1.UseStaticFiles(options);
  15. }
或者這樣講有點抽象,這就簡單的舉個範例讓大家更容易了解,下面的範例是透過設定 StaticFileOptions 公開 MyStaticFiles 目錄資料夾作為存放靜態檔案的位置
  1. public void Configure(IApplicationBuilder app)
  2. {
  3. app.UseStaticFiles(); // 預設公開位置 wwwroot
  4. app.UseStaticFiles(new StaticFileOptions
  5. {
  6. FileProvider = new PhysicalFileProvider(
  7. Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
  8. RequestPath = "/StaticFiles"
  9. });
  10. }

UseStaticFiles 指定 StaticOptions
UseStaticFiles 指定靜態檔案路徑與此方法有點類似,都是設定其 StaticOptions 參數資料,差異是上面的方法僅提供設定路徑位置 RequestPath,此方法提供設定範圍比較廣,可以定義 StaticOptions 類別更多的細節,先看看 API 簽章
  1. /// <summary>Enables static file serving with the given options</summary>
  2. /// <param name="app"></param>
  3. /// <param name="options"></param>
  4. /// <returns></returns>
  5. public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app, StaticFileOptions options)
  6. {
  7. if (app == null)
  8. throw new ArgumentNullException(nameof (app));
  9. if (options == null)
  10. throw new ArgumentNullException(nameof (options));
  11. return app.UseMiddleware<StaticFileMiddleware>((object) Microsoft.Extensions.Options.Options.Create<StaticFileOptions>(options));
  12. }
甚麼時候有可能會用到呢? 舉例來說有時希望在回傳靜態檔案時加上 cache 機器,讓瀏覽器的 Browser 幫忙做點事不用相同檔案的 Request 重複跟 Server 要資料,這時就可以透過 OnPrepareResponse 方法在回傳前做點小加工,實作方式如下
  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  2. {
  3. var cachePeriod = "600";
  4. app.UseStaticFiles(new StaticFileOptions
  5. {
  6. OnPrepareResponse = ctx =>
  7. {
  8. ctx.Context.Response.Headers.Append("Cache-Control", $"public, max-age={cachePeriod}");
  9. }
  10. });
  11. }
在回傳的 Head 上加上 cache 有效時間為 600 秒,從網頁 Response 結果就可以看出設定成功

後記
以上簡單介紹關於 UseStaticFiles 的基本應用與說明,在其中有更多進階的應用像是檔案授權、如何開啟靜態檔案目錄方式瀏覽、提供預設文件的方式等更多情境的應用,如果有需要可以參考官方網站的說明與 sample code : 傳送門在此,當然對以上的內容說是有疑問的地方歡迎隨時提出來,謝謝

參考
ASP.NET Core 中的靜態檔案

Related Posts:

  • [CheatSheets] ASP.NET Memory Management 前言  在 ASP.NET 中記憶體管理一直是個很重要的議題,Pro.NET Memory Management 一書的作者為了讓開發者更容易了解其中這神祕的世界,製作了兩張關於 .NET Core 與 .NET GC 記憶體相關摘要的海報,看完覺得實用特記錄在部落格中,做為日後小抄使用 :) 海報內容僅是對於 static 與 dynamic 的兩個觀點作介紹,當然其中還是有很多細節與實作方式需要了解,如果更有興趣可以… Read More
  • [.NETCore] ASP.Net Core 使用 Big5 中文編碼 問題 在 .NET Framework 時要取得中文編碼可以使用  Encoding.GetEncoding("BIG5"),今天在練習專案時遇到類似的情境很直覺的在將 Code 套用在 .NET Core 上,沒想到竟然發生錯誤,這邊簡單紀錄遇到這問題該怎麼解決以及根本原因,有任何問題歡迎留言一起討論 解決方式  "ArgumentException: 'Big5' is not a support… Read More
  • [.NETCore] ASP.NET Core - Logging 日誌初體驗 (二)前言 在上一篇文章介紹了在 ASP.Net Core 如何使用內建的 logging,以及 ILogger 與 ILoggerFactory 還有篩選記錄的方法,這篇再繼續介紹在 logging 中一些基本觀念與應用,如果有寫不清楚的地方可以搭配 MSDN 官網的 ASP.NET Core logging 一起服用,若有問題歡迎提出一起討論或是給予指導 LogLevel 紀錄 log 時候都會指定紀錄… Read More
  • [NETCore] Polly 的超時 TimeOut 和 Wrap 策略介紹 Polly 是一套 .NET 處理瞬間故障的函式庫,提供開發人員用 Fluent API 方式及 Thread Safe 處理服務瞬間故障的策略,並提供重試(Retry)、斷路(Circuit-breaker)、超時(Timeout)、隔離(Bulkhead Isolation)、緩存(Cache)、回退(Fallback) 等機制,在上一篇 [NETCore] 使用 Polly 實現重試 (Retry) 策略 分享了 … Read More
  • [.NETCore] ASP.NET Core - Logging 日誌初體驗 (一)前言 在前一篇的文章裡介紹 ASP.Net Core 中如使用 NLog 將日誌紀錄於指定的位置檔案中,在ASP.Net Core 內建 logging framework ,專門負責記錄 log 與提供 API 與第三方紀錄套件像是 NLog、Log4Net 整合搭配使用,這篇文章是閱讀 MSDN 官網的 ASP.NET Core logging 後摘錄重點筆記,若有問題歡迎提出一起討論或是給予指導 使用 I… Read More

0 意見:

張貼留言

Copyright © 2025 m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com