在之前介紹的附件管理模塊裡面《Winform開發框架之通用附件管理模塊》以及《Winform開發框架之附件管理應用》,介紹了附件的管理功能,通過對資料庫記錄的處理和文件的管理,實現了附件文件和記錄的整合管理,可以運用在單機版的WInform框架,也可以使用在分散式的混合式開發框架中,隨著一些開發場景... ...
在之前介紹的附件管理模塊裡面《Winform開發框架之通用附件管理模塊》以及《Winform開發框架之附件管理應用》,介紹了附件的管理功能,通過對資料庫記錄的處理和文件的管理,實現了附件文件和記錄的整合管理,可以運用在單機版的WInform框架,也可以使用在分散式的混合式開發框架中,隨著一些開發場景的豐富,我們需要以FTP方式上傳文件,因此對這個附件管理模塊進行擴展,以便適合更多的實際項目需求。
1、FTP上傳、HTTP文件預覽實現思路
我們設想的附件管理,底層都是需要在Winform、Web等開發項目上重用的,因此底層的設計需要考慮好對應的處理,另外後面可以利用WInform的HTML編輯控制項、或者Web的HTML編輯控制項進行集成,附件則是統一在一個組件裡面實現的。
藉助FTP的文件上傳,我們單機版本或者基於區域網的Winform界面程式,也可以單獨構建一個FTP伺服器,實現文件的共用;而分散式的混合式開發框架中,對於文件的上傳,可以選擇基於服務的文件系統寫入,同時也可以基於FTP的方式上傳。
基於混合式框架的FTP方式上傳文件,其邏輯關係如下所示。
這樣文件通過FTP方式上傳的文件系統後,我們在文件系統裡面搭建一個HTTP服務,這樣對應上的HTTP地址就可以實現文件的下載,以及圖片的查看等操作了(可以在HTML編輯器中實現)。
2、引入FTP組件實現文件上傳
使用FTP上傳,雖然在自己的公用類庫裡面有FTPHelper類可以使用,不過相對來說,我更願意引入更為完善強大的FTP開源組件進行相關的處理,這裡我們使用FluentFTP這個組件(GitHub地址:https://github.com/hgupta9/FluentFTP ),這個是一個應用很廣,功能很強大的FTP組件。
FluentFTP是一款老外開發的基於.Net的支持FTP及的FTPS 的FTP類庫,FluentFTP是完全托管的FTP客戶端,被設計為易於使用和易於擴展。它支持文件和目錄列表,上傳和下載文件和SSL / TLS連接。它可以連接到Unix和Windows IIS建立FTP伺服器。這個項目是完全開發托管C #。
這個組件的使用代碼,這裡粘貼一下,以便總體有一個直觀的瞭解吧。
// create an FTP client FtpClient client = new FtpClient("123.123.123.123"); // if you don't specify login credentials, we use the "anonymous" user account client.Credentials = new NetworkCredential("david", "pass123"); // begin connecting to the server client.Connect(); // get a list of files and directories in the "/htdocs" folder foreach (FtpListItem item in client.GetListing("/htdocs")) { // if this is a file if (item.Type == FtpFileSystemObjectType.File){ // get the file size long size = client.GetFileSize(item.FullName); } // get modified date/time of the file or folder DateTime time = client.GetModifiedTime(item.FullName); // calculate a hash for the file on the server side (default algorithm) FtpHash hash = client.GetHash(item.FullName); } // upload a file client.UploadFile(@"C:\MyVideo.mp4", "/htdocs/big.txt"); // rename the uploaded file client.Rename("/htdocs/big.txt", "/htdocs/big2.txt"); // download the file again client.DownloadFile(@"C:\MyVideo_2.mp4", "/htdocs/big2.txt"); // delete the file client.DeleteFile("/htdocs/big2.txt"); // delete a folder recursively client.DeleteDirectory("/htdocs/extras/"); // check if a file exists if (client.FileExists("/htdocs/big2.txt")){ } // check if a folder exists if (client.DirectoryExists("/htdocs/extras/")){ } // upload a file and retry 3 times before giving up client.RetryAttempts = 3; client.UploadFile(@"C:\MyVideo.mp4", "/htdocs/big.txt", FtpExists.Overwrite, false, FtpVerify.Retry); // disconnect! good bye! client.Disconnect();
有了這些瞭解,我們在普通Winform程式或者混合式框架的的程式中,我們通過配置指定FTP的相關信息,就可以在代碼裡面載入這些信息,進行FTP的登陸、文件上傳、下載等操作了。
3、附件管理模塊實現
有了上面的思路和組件的輔助,我們對原來的附件管理模塊進行相關的升級處理即可實現FTP上傳模式的處理了。
首先為了方便,我們先定義一個獲取FTP伺服器、用戶名、密碼等參數的配置實體類,如下所示。
/// <summary> /// FTP配置信息 /// </summary> [DataContract] [Serializable] public class FTPInfo { /// <summary> /// 預設構造函數 /// </summary> public FTPInfo() { } /// <summary> /// 參數化構造函數 /// </summary> /// <param name="server"></param> /// <param name="user"></param> /// <param name="password"></param> public FTPInfo(string server, string user, string password, string baseUrl) { this.Server = server; this.User = user; this.Password = password; this.BaseUrl = baseUrl; } /// <summary> /// FTP服務地址 /// </summary> [DataMember] public string Server { get; set; } /// <summary> /// FTP用戶名 /// </summary> [DataMember] public string User { get; set; } /// <summary> /// FTP密碼 /// </summary> [DataMember] public string Password { get; set; } /// <summary> /// FTP的基礎路徑,如可以指定為IIS的路徑:http://www.iqidi.com:8000 ,方便下載打開 /// </summary> [DataMember] public string BaseUrl { get; set; } }
定義一個函數,專門用來提取配置文件裡面的相關FTP參數的,如下所示。
/// <summary> /// 獲取配置的FTP配置參數 /// </summary> /// <returns></returns> private FTPInfo GetFTPConfig() { var ftp_server = config.AppConfigGet("ftp_server"); var ftp_user = config.AppConfigGet("ftp_user"); var ftp_pass = config.AppConfigGet("ftp_password"); var ftp_baseurl = config.AppConfigGet("ftp_baseurl"); return new FTPInfo(ftp_server, ftp_user, ftp_pass, ftp_baseurl); }
其中我們的配置文件如下所示。
使用FluentFTP的組件代碼如下所示。
//使用FluentFTP操作FTP文件 FtpClient client = new FtpClient(ftpInfo.Server, ftpInfo.User, ftpInfo.Password);
然後調用FTP組件對目錄進行判斷,無則創建一個即可。
//確定日期時間目錄(格式:yyyy-MM),不存在則創建 string savePath = string.Format("/{0}-{1:D2}/{2}", DateTime.Now.Year, DateTime.Now.Month, category); bool isExistDir = client.DirectoryExists(savePath); if(!isExistDir) { client.CreateDirectory(savePath); }
最後使用組件上傳文件即可,這裡上傳文件,由於前面FileUploadInfo實體類裡面存儲的是位元組數組,因此也是採用FTP組件直接上傳位元組數組即可。
//使用FTP上傳文件 //避免文件重覆,使用GUID命名 var ext = FileUtil.GetExtension(info.FileName); var newFileName = string.Format("{0}{1}", Guid.NewGuid().ToString(), ext);//FileUtil.GetFileName(file); savePath = savePath.UriCombine(newFileName); bool uploaded = client.Upload(info.FileData, savePath, FtpExists.Overwrite, true);
文件上傳到文件伺服器後,剩下的就是把相關的信息存儲到附件管理模塊的數據表裡面即可,這樣可以在使用的時候,直接使用資料庫裡面的信息,如果是需要查看圖片或者下載文件,那麼拼接好相關的HTTP地址即可,我們來看看對應的資料庫記錄截圖如下所示。
有了這些基礎信息,我們可以同時改造我之前介紹過的Winform之HTML編輯控制項:ZetaHtmlEditControl了(分享一個Winform裡面的HTML編輯控制項Zeta HTML Edit Control,漢化附源碼),我對這個控制項所有英文的菜單、工具欄、對話框、提示內容等資源進行中文化後,併在工具欄中增加插入圖片、列印功能後,界面如下所示。
預設情況下,我們加入圖片的方式,肯定還是基於本地文件的方式了;但是經過我們改造使用FTP上傳文件方式後,在控制項上獲得HTTP地址,就可以對圖片文件進行預覽展示的操作了。
這種方法構造的圖片地址,屬於標準的URL地址,可以在各個地方進行查看的,如下界面所示。
這個就是ZetaHtmlEditControl控制項,整合我們前面已經完成了FTP上傳模式的附件管理模塊,實現編輯線上HTML的功能,這樣的HTML內容,同樣可以適合在Web界面下的HTML編輯器上進行展示了。
以上就是我為整個WInform開發框架構造的項目組件,增加的FTP上傳方式,同時完善了對應的場景需求,在ZetaHtmlEditControl控制項上實現編輯線上HTML的功能,希望開發的思路對您有所增益。