主題:如何在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