主題:如何在ASP.NET Core中自定義Azure Storage File Provider
作者: Lamond Lu
地址: https://www.cnblogs.com/lwqlun/p/10406566.html
專案原始碼: https://github.com/lamondlu/AzureFileProvider

背景
ASP.NET Core是一個擴充套件性非常高的框架,開發人員可以根據自己的需求擴展出想要的功能。File Provider是ASP.NET Core中的一個重要元件,透過這個元件,開發人員可以暴露一組檔案,並允許應用程式像訪問靜態檔案一樣訪問暴露的檔案。
ASP.NET Core中內建了3種File Provider
-
PhysicalFileProvider– 用來訪問和應用程式部署在一起的靜態檔案 -
ManifestEmbeddedFileProvider– 用來訪問程式集中的內嵌檔案 -
CompositeFileProvider– 將多個File Provider合併使用
那麼如何自定義一個File Provider呢?比如如何將Azure Files Storage中的檔案暴露給ASP.NET Core應用程式。今天我們來演示一下,如果透過實現IFileProvider 介面來實現一個Azure Files Storage Provider。
本文中只針對Azure Files Storage, Azure Blob Storage的實現可以參見Filip w的博文
建立.NET Core Library專案
首先我們使用Visual Studio 2017,建立一個Class Library專案, 命名為AzureFileProvider

為了使用IFileProvider介面和Azure Storage服務,這裡我們需要使用Nuget引入2個庫
-
Microsoft.AspNetCore.App
-
WindowsAzure.Storage
建立AzureFileProvider
為了建立一個ASP.NET Core支援的File Provider, 我們就需要自己建立一個類,並讓它實現IFileProvider介面。
這裡首先我們建立一個類AzureFileProvider, 它實現了IFileProvider介面

從以上程式碼中,我們可以瞭解到,IFileProvider介面定義了3個需要實現方法
-
GetDirectoryContents– 這個方法是用來獲取指定目錄下的內容的 -
GetFileInfo– 這個方法使用來獲取指定檔案內容的 -
Watch– 這個方法是用來監聽檔案變更的,這個暫時不需要實現它
實現GetDirectoryContents方法
為了實現GetDirectoryContents方法,我們需要首先建立一個IDirectoryContents介面的實現類, 因為它是這個方法的傳回型別。
我們建立一個類AzureStorageDirectoryContents, 它實現了IDirectoryContents介面。

程式碼解釋:
這裡
IDirectoryContents其實就是為了顯示指定目錄中的檔案結構
IFileInfo介面物件既可以表示檔案也可以表示子目錄,這個介面的2個實現我會在後面說明這裡我們透過建構式,將指定檔案夾內的檔案結構註入到了
AzureStorageDirectoryContents雷中。
下麵我們就可以來新增GetDirectoryContents方法的實現了。

程式碼解釋:
這裡我們透過建構式為
AzureFileProvider類註入了一個Azure Files Storage強型別配置類AzureStorageSetting, 它的資料源是appSettings.json, 後續我們會透過強型別配置將其註入
GetRootDirectory方法是透過Azure Files Storage配置,獲得Azure Files Storage中檔案集合的根目錄
GetDirectoryContents中subpath.Substring(1)程式碼的作用是去除subpath帶的第一個“/”。如果不去除,會讀取不到檔案這裡我們使用了
ListFilesAndDirectoriesSegmentedAsync方法獲取了指定目錄中所有的檔案和目錄如果是檔案,我們會實體化一個
AzureFileInfo物件,如果是一個目錄,我們會實體化一個AzureDirectoryInfo物件最終我們將讀取到的所有檔案和目錄資訊透過
AzureStorageDirectoryContents類的建構式註入。
建立AzureFileInfo和AzureDirectoryInfo
為了區分檔案和目錄,我們建立2個新類AzureFileInfo和AzureDirectoryInfo。 他們都實現了IFileInfo介面。
AzureFileInfo

程式碼解釋
這裡我們透過
AzureFileInfo的建構式傳入了一個CloudFile物件, 這個物件將作為Name,PhysicalPath,LastModified等屬性的資料源。我們使用
CloudFile物件DownloadRangeToStreamAsync, 將其對應的檔案流下載。註意這裡載入檔案流之後,需要將檔案流的Position置0(即流的頭部)檔案的長度即檔案流的長度
強制設定
IsDirectory屬性為false, 因為當前處理的是檔案
AzureDirectoryInfo

程式碼解釋
這裡我們透過
AzureDirectoryInfo的建構式傳入了一個CloudFileDirectory物件, 這個物件將作為Name,PhysicalPath,LastModified等屬性的資料源。強制設定
IsDirectory屬性為true, 因為當前處理的是目錄這裡我們沒有實現
Length屬性和CreateReadStream, 因為我們處理的是目錄, 這2個屬性沒有必要實現。
實現GetFileInfo方法
相對於GetDirectoryContents方法的實現,GetFileInfo方法就簡單多了,我們只需要根據當前指定的subpath, 將檔案資訊傳回即可。

如何啟用AzureFileProvider
下麵我們來試驗一下我們編寫的AzureFileProvider是否能執行成功。
首先我們建立一個預設ASP.NET Core Api專案,並取用上一步中編譯好的程式集AzureFileProvider.dll。
appSettings.json中, 我們需要定義Azure Files Storage的配置
例:

第二步,我們需要修改Startup.cs檔案的Configure方法。

程式碼解釋
這裡我們使用強型別配置系結,獲取了appSettings.json中的Azure Files Storage的配置
在配置靜態檔案中介軟體部分,我們透過
StaticFileOptions配置物件,指定了當前應用使用AzureFileProvider。為了演示效果,我這裡也啟用了DirectoryBrowser中介軟體,即可以使用網頁檢視目錄結構。這個功能比較危險,在正式專案很少使用。所以正式使用時,最好將這段程式碼刪掉。
最終效果
現在我們啟動當前專案, 訪問”/files”, 即可檢視到當前指定Azure Files Storage中的所有檔案和目錄

專案原始碼
https://github.com/lamondlu/AzureFileProvider
Nuget程式集
以上類庫,我已經釋出到了Nuget上, 如果你不想每次都把前面的程式碼寫一遍,可以直接安裝這個程式集來使用。
Install-Package LamondLu.AzureFileProvider
知識星球