利用一個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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...