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