利用一個ASP.NET Core應用來發佈靜態文件

来源:http://www.cnblogs.com/artech/archive/2016/12/07/static-file-for-asp-net-core-01.html
-Advertisement-
Play Games

雖然ASP.NET Core是一款“動態”的Web服務端框架,但是在很多情況下都需要處理針對靜態文件的請求,最為常見的就是這對JavaScript腳本文件、CSS樣式文件和圖片文件的請求。針對不同格式的靜態文件請求的處理,ASP.NET Core為我們提供了三個中間件,它們將是本章論述的重點。不過在... ...


雖然ASP.NET Core是一款“動態”的Web服務端框架,但是在很多情況下都需要處理針對靜態文件的請求,最為常見的就是這對JavaScript腳本文件、CSS樣式文件和圖片文件的請求。針對不同格式的靜態文件請求的處理,ASP.NET Core為我們提供了三個中間件,它們將是本系列文章論述的重點。不過在針對對它們展開介紹之前,我們照理通過一些簡單的實例來體驗一下如何在一個ASP.NET Core應用中發佈靜態文件。[本文已經同步到《ASP.NET Core框架揭秘》之中]

目錄
一、以Web的形式讀取文件
二、瀏覽目錄內容
三、顯示預設頁面
四、映射媒體類型

一、以Web的形式讀取文件

我們創建的演示實例是一個簡單的ASP.NET Core控制台應用,它具有如下圖所示的項目結構。我們可以看到在預設作為WebRoot的目錄(wwwroot)下,我們將JavaScript腳本文件、CSS樣式文件和圖片文件存放到對應的子目錄(js、css和img)下,我們將把這個目錄的所有文件以Web的形式發佈出來,客戶端可以訪問相應的URL來獲取這些文件。

1

針對靜態文件的請求是通過一個名為StaticFileMiddleware的中間件來實現的,這個中間件類型定義在NuGet包“Microsoft.AspNetCore.StaticFiles”中,所以我們需要預先按照這個NuGet包。整個應用只包含如下所示的這幾行代碼,StaticFileMiddleware這個中間件的註冊是通過調用ApplicationBuilder的擴展方法UseStaticFiles來完成的。

   1: public class Program
   2: {
   3:     public static void Main()
   4:     {
   5:         new WebHostBuilder()
   6:             .UseContentRoot(Directory.GetCurrentDirectory())
   7:             .UseKestrel()
   8:             .Configure(app => app.UseStaticFiles())
   9:             .Build()
  10:             .Run();
  11:     }
  12: }

除了註冊必需的StaticFileMiddleware中間件之外,我們還調用了WebHostBuilder的UseContentRoot方法將當前項目的根目錄作為ContentRoot目錄。我們知道ASP.NET Core應用具有兩個重要的根目錄,它們分別是ContentRoot和WebRoot,後者也是對外發佈的靜態文件預設使用的根目錄。由於WebRoot目錄的預設路徑就是“{contentroot}/wwwroot”,所示上面這段程式就是將項目中的這個wwwroot目錄下的所有靜態文件發佈出來。

當這個程式運行之後,我們就可以通過向對應URL發送HTTP請求的方式來獲取某個的文件,這個URL由文件相當於wwwroot目錄的路徑來決定。比如JPG文件“~/wwwroot/img/dophin1.jpg”對應的URL為“http://
localhost:5000/img/dophin1.jpg”。我們直接利用瀏覽器訪問這個URL,目標圖片會直接顯示出來。

2

上面我們通過一個簡單的實例將WebRoot所在目錄下的所有靜態文件直接發佈出來。如果我們需要發佈的靜態文件存儲在其他目錄下呢?依舊是演示的這個應用,現在我們將一些文檔存儲在如下圖所示的“~/doc/”目錄下並以Web的形式發佈出來,我們的程式又該如何編寫呢?

3

我們知道ASP.NET Core應用大部分情況下都是利用一個FileProvider對象來讀取文件的,它在處理針對靜態文件的請求是也不例外。對於我們調用ApplicationBuilder的擴展方法UseStaticFiles方法註冊的這個類型為StaticFileMiddleware的中間件,其內部具有一個FileProvider和請求路徑的映射關係。如果調用UseStaticFiles方法沒有指定任何的參數,那麼這個映射關係的請求路徑就是應用的基地址(PathBase),而FileProvider自然就是指向WebRoot目錄的PhysicalFileProvider。

上述的這個需求可以通過顯式註冊這個映射的方式來實現,為此我們在現有程式的基礎上額外添加了一次針對UseStaticFiles方法的調用,並通過指定的參數(是一個StaticFileOptions對象)顯式指定了採用的FileProvider(針對“~/doc/”的PhysicalFileProvider)和請求路徑(“/documents”)。

   1: public class Program
   2: {
   3:     public static void Main()
   4:     {
   5:         string contentRoot = Directory.GetCurrentDirectory();
   6:         new WebHostBuilder()
   7:             .UseContentRoot(contentRoot)
   8:             .UseKestrel()
   9:             .Configure(app => app
  10:                 .UseStaticFiles()
  11:                 .UseStaticFiles(new StaticFileOptions {
  12:                      FileProvider = new PhysicalFileProvider(Path.Combine(contentRoot, "doc")),
  13:                      RequestPath = "/documents"
  14:                     }))
  15:             .Build()
  16:             .Run();
  17:     }
  18: }

按照上面這段程式指定的映射關係,對於存儲在“~/doc/”目錄下的這個PDF文件(“checklist.pdf”),發佈在Web上的URL為“http://localhost:5000/documents/checklist.pdf”。當我們在瀏覽器上請求這個地址時,該PDF文件的內容將會按照如下圖所示的形式顯示在瀏覽器上。

4

二、瀏覽目錄內容

註冊的StaticFileMiddleware中間件只會處理針對某個具體靜態文件的額請求,如果我們向針對某個目錄的URL發送HTTP請求(比如“http://localhost:5000/img/”),得到的將是一個狀態為404的響應。不過我們可以通過註冊另一個名為DirectoryBrowserMiddleware的中間件來顯示請求目錄的內容。具體來說,這個中間件會返回一個HTML頁面,請求目錄下的所有文件將以表格的形式包含在這個頁面中。對於我們演示的這個應用來說,我們可以按照如下的方式調用UseDirectoryBrowser方法來註冊這個DirectoryBrowserMiddleware中間件。

   1: public class Program
   2: {
   3:     public static void Main()
   4:     {
   5:         string contentRoot = Directory.GetCurrentDirectory();
   6:         IFileProvider fileProvider = new PhysicalFileProvider(
   7:             Path.Combine(contentRoot, "doc"));
   8:         new WebHostBuilder()
   9:             .UseContentRoot(contentRoot)
  10:             .UseKestrel()
  11:             .Configure(app => app
  12:                 .UseStaticFiles()
  13:                 .UseStaticFiles(new StaticFileOptions {
  14:                     FileProvider = fileProvider,
  15:                     RequestPath = "/documents"
  16:                 })
  17:                 .UseDirectoryBrowser()
  18:                 .UseDirectoryBrowser(new DirectoryBrowserOptions {
  19:                         FileProvider = fileProvider,
  20:                         RequestPath = "/documents"
  21:                 }))
  22:             .Build()
  23:             .Run();
  24:     }
  25: }

當上面這個應用啟動之後,如果我們利用瀏覽器向針對某個目錄的URL(比如“http://localhost:5000/”或者“http://localhost:5000/img/”),目標目錄的內容(包括子目錄和文件)將會以下圖所示的形式顯示在一個表格中。不僅僅如此,子目錄和文件均會顯示為鏈接,指向目標目錄或者文件的URL。

5

三、顯示預設頁面

從安全的角度來講,利用註冊的UseDirectoryBrowser中間件顯示一個目錄瀏覽頁面會將整個目標目錄的介面和所有文件全部暴露出來,所以這個中間件需要根據自身的安全策略謹慎使用。對於針對目錄的請求,另一種更為常用的響應策略就是顯示一個保存在這個目錄下的預設頁面。按照約定,作為預設頁面的文件一般採用如下四種命名方式:default.htm、default.html、index.htm或者index.html。針對目標目錄下預設頁面的呈現實現在一個名為DefaultFilesMiddleware的中間件中,我們演示的這個應用可以按照如下的方式調用UseDefaultFiles方法來註冊這個中間件。

   1: public class Program
   2: {
   3:     public static void Main()
   4:     {
   5:         string contentRoot = Directory.GetCurrentDirectory();
   6:         IFileProvider fileProvider = new PhysicalFileProvider(Path.Combine(contentRoot, "doc"));
   7:  
   8:         new WebHostBuilder()
   9:             .UseContentRoot(contentRoot)
  10:             .UseKestrel()
  11:             .Configure(app => app
  12:                 .UseDefaultFiles()
  13:                 .UseDefaultFiles(new DefaultFilesOptions{
  14:                     RequestPath = "/documents",
  15:                     FileProvider = fileProvider,
  16:                 })
  17:                 .UseStaticFiles()
  18:                 .UseStaticFiles(new StaticFileOptions
  19:                 {
  20:                     FileProvider = fileProvider,
  21:                     RequestPath = "/documents"
  22:                 })
  23:                 .UseDirectoryBrowser()
  24:                 .UseDirectoryBrowser(new DirectoryBrowserOptions
  25:                 {
  26:                     FileProvider = fileProvider,
  27:                     RequestPath = "/documents"
  28:                 }))
  29:             .Build()
  30:             .Run();
  31:     }
  32: }

現在我們在“~/wwwroot/img/”目錄下創建一個名為index.htm的預設頁面,現在利用瀏覽器訪問這個目錄對應的URL(“http://localhost:5000/img/”),顯示就時這個頁面的內容。

6

我們必須在註冊StaticFileMiddleware和DirectoryBrowserMiddleware之前註冊DefaultFilesMiddleware,否則它起不了任何作用。由於DirectoryBrowserMiddleware和DefaultFilesMiddleware這兩個中間件處理的均是針對目錄的請求,如果DirectoryBrowserMiddleware先被註冊,那麼顯示的總是目錄的內容。若DefaultFilesMiddleware先被註冊,在預設頁面不存在情況下回顯示目錄的內容。至於為什麼要先於StaticFileMiddleware之前註冊DefaultFilesMiddleware,則是因為後者是通過採用URL重寫的方式實現的,也就是說這個中間件會將針對目錄的請求改寫成針對預設頁面的請求,而最終針對預設頁面的請求還得依賴StaticFileMiddleware完成。

DefaultFilesMiddleware中間件在預設情況下總是以約定的名稱(default.htm、default.html、index.htm或者index.html)在當前請求的目錄下定位預設頁面。如果我們希望作為預設頁面的文件不能按照這樣的約定命名(比如readme.htm),我們需要按照如下的方式顯式指定預設頁面的文件名。

   1: public class Program
   2: {
   3:     public static void Main()
   4:     {
   5:         string contentRoot = Directory.GetCurrentDirectory();
   6:         IFileProvider fileProvider = new PhysicalFileProvider(Path.Combine(contentRoot, "doc"));
   7:  
   8:         DefaultFilesOptions options1 = new DefaultFilesOptions();
   9:         DefaultFilesOptions options2 = new DefaultFilesOptions{
  10:             RequestPath = "/documents",
  11:             FileProvider = fileProvider
  12:         };
  13:         options1.DefaultFileNames.Add("readme.htm");
  14:         options2.DefaultFileNames.Add("readme.htm");
	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 從0開始搭建SQL Server AlwaysOn 第四篇(配置異地機房節點) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www.cnblogs.com/lyhabc/p/4682028.html第三篇http://www.cn ...
  • 安裝Oracle時出現環境變數Path的值大於1023的解決辦法 ...
  • 建庫 CREATE DATABASE 資料庫名 ON[PRIMARY] --預設屬於PRIMARY主文件組,可省略 ( NAME='', --主數據文件的邏輯名 名稱 FILEAME='', --主數據文件的物理名 路徑 .mdf 次資料庫為.ndf SIZE=5mb, --主數據文件初始大小 MA ...
  • 前言 很多時候資料庫的TempDB、日誌等文件的暴增可能導致磁碟空間被占滿,如果日常配置不到位,往往會導致資料庫故障,業務被迫中斷。 這種文件暴增很難排查,經驗不足的一些運維人員可能更是無法排查具體原因,導致問題不能徹底解決。 場景描述 客戶系統比較穩定,用了5台機器做了AlwaysOn高可用組,完 ...
  • MySQL 執行計劃 在SQL優化時,查看執行計劃,是一個有效的途徑。 1、Explain 語法 2、Explain 列說明 在mysql中,一個執行通常包括面的列: 下麵的列說明中,會使用這個例子進行說明。 2.1 id 通過Id,可以看到sql的執行順序。 預設情況下,一個簡單的select的i ...
  • 前言:打算做一個藥材價格查詢的功能,但剛開始一點數據都沒有靠自己找信息錄入的話很麻煩的,所以只有先到其它網站抓取存到資料庫再開始做這個了。 HtmlAgilityPack在c#里應該很多人用吧,簡單又強大。之前也用它做過幾個爬取信息的小工具。不過很久了源代碼都沒有了,都忘了怎麼用了,這次也是一點一點 ...
  • 控制項封裝的部分說明 可能有人覺得應該前後端分離,我也承認這是應該的方向,我們也在考慮使用ng2等簡化前端。但是,我們封裝控制項還是因為如下原因綜合考慮的: 我們這是個框架,上面支撐了許多個應用,包含幾百個頁面,每個頁面都去寫一堆的js\css\html標簽可能對開發人員來說非常麻煩,且每個人寫的都可能 ...
  • 1>> 力軟信息化系統快速開發框架 2>> 金碟友商網 3>> ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...