前言
為什麼要寫這邊博文呢?其實,就是使用C#WebClient類訪問由IIS搭建的http文件服務器的問題花了我足足兩天的時間,因此,有必要寫下自己所學到的,同時,也能讓廣大的博友學習學習一下。
本文足如有不足之處,請在下方留言提出,我會進行改正的,謝謝!
搭建IIS文件服務器
本博文使用的操作系統為Windows 10 企業版,其他Windows系統類似,請借鑒:
一、當然,開始肯定沒有IIS,那該怎麼辦?需要一個軟件環境進行搭建,具體方法如下:
1)打開“控制面板”,找到“程序與功能”,如下圖所示:
2)點進去之後,找到“啟用或關閉Windows功能”,如下圖所示:
3)點進去之後,將“Internet Information Services”下所有節點都打勾(這樣就搭建了一個功能完全的HTTP/FTP服務器),注意“WebDAV發布”必須要安裝,這個跟文件服務器中文件訪問權限有著很大的關系,如果想對服務器中某個具有讀寫權限的文件夾進行讀寫,就必須開啟該選項,如下圖所示:
4)等待安裝完畢,請耐心等待, 如下圖所示:
5)完成之後,點擊“關閉”按鈕即可,然後,打開“控制面板”,找到“管理工具”,如下圖所示:
6)點擊“管理工具”後,找到“Internet Information Services (IIS)管理器”,打開它,如下圖所示:
7)進去之後,就已經進入了IIS的管理界面,我們只用到的功能為紅色框內的IIS功能,如下圖所示:
8)第一搭建IIS,會出現一個默認的Web網站,我們將鼠標移到“Default Web Site”上方,右鍵彈出菜單,在菜單中點擊“刪除”將該網站刪除,如下圖所示:
9)添加自己的一個網站,鼠標移到“網站”上方,右鍵點擊鼠標,彈出菜單,在菜單中點擊“添加網站”,如下圖所示:
10)根據如下圖所說的步驟,填寫網站名稱及選擇物理路徑,其他默認即可,然後點擊“確定”按鈕:
11)本網站僅作為文件服務器,因此,將服務器的文件浏覽功能打開,以便浏覽,具體操作為鼠標雙擊“目錄浏覽”後,將“操作”一欄裡的“啟用”打開,如下圖所示:
12)鼠標雙擊“WebDAV創作規則”,如下圖所示:
13)點擊“WebDAV設置”,如下圖所示:
14)將①②所示紅色框內的屬性設置為圖中所示的屬性,並點擊“應用”,如下圖所示:
15)返回到“WebDAV創作規則”,點擊“添加創作規則”,如下圖所示:
16)在彈出的“添加創作規則”,將“允許訪問此內容”選中,權限“讀取、源、寫入”都打勾,點擊“確定”按鈕關閉,如下圖所示:
17)返回到“WebDAV創作規則”,點擊“啟用WebDAV”,如下圖所示:
18)雙擊“身份驗證”,將“匿名身份驗證”(客戶端讀取文件)及“Windows身份驗證”(客戶端寫入、刪除)啟用,如下所示:
19)為了能讓文件服務器具有寫入、刪除功能,可以在現有Windows系統賬戶上新建一個隸屬於“Power Users”的賬戶“test”(密碼:123),如下圖所示:
以上關於如何創建賬戶的內容,請自行百度
20)為了能讓test賬戶順利訪問存放於E盤下的“TestWebSite”文件夾,需要為該文件夾設置Power Users組的訪問權限,如下圖所示:
關於如何將特定組或用戶設置權限的問題,請自行百度
21)查看本機IIS的IP地址,並在浏覽器輸入該IP,將會顯示以下內容,如下圖所示:
22)自此,IIS文件服務器的搭建已經完畢。
使用C#WebClient訪問IIS文件服務器
本博文使用的的IDE為VS2015,在使用WebClient類之前,必須先引用System.Net命名空間,文件下載、上傳與刪除的都是使用異步編程,也可以使用同步編程,
這裡以異步編程為例:
1)文件下載:
1 static void Main(string[] args) 2 { 3 //定義_webClient對象 4 WebClient _webClient = new WebClient(); 5 //使用默認的憑據——讀取的時候,只需默認憑據就可以 6 _webClient.Credentials = CredentialCache.DefaultCredentials; 7 //下載的鏈接地址(文件服務器) 8 Uri _uri = new Uri(@"http://192.168.1.103/test.doc"); 9 //注冊下載進度事件通知 10 _webClient.DownloadProgressChanged += _webClient_DownloadProgressChanged; 11 //注冊下載完成事件通知 12 _webClient.DownloadFileCompleted += _webClient_DownloadFileCompleted; 13 //異步下載到D盤 14 _webClient.DownloadFileAsync(_uri, @"D:\test.doc"); 15 Console.ReadKey(); 16 } 17 18 //下載完成事件處理程序 19 private static void _webClient_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) 20 { 21 Console.WriteLine("Download Completed..."); 22 } 23 24 //下載進度事件處理程序 25 private static void _webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) 26 { 27 Console.WriteLine($"{e.ProgressPercentage}:{e.BytesReceived}/{e.TotalBytesToReceive}"); 28 }
運行結果如下:
2)文件上傳:
static void Main(string[] args) { //定義_webClient對象 WebClient _webClient = new WebClient(); //使用Windows登錄方式 _webClient.Credentials = new NetworkCredential("test", "123"); //上傳的鏈接地址(文件服務器) Uri _uri = new Uri(@"http://192.168.1.103/test.doc"); //注冊上傳進度事件通知 _webClient.UploadProgressChanged += _webClient_UploadProgressChanged; //注冊上傳完成事件通知 _webClient.UploadFileCompleted += _webClient_UploadFileCompleted; //異步從D盤上傳文件到服務器 _webClient.UploadFileAsync(_uri,"PUT", @"D:\test.doc"); Console.ReadKey(); } //下載完成事件處理程序 private static void _webClient_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e) { Console.WriteLine("Upload Completed..."); } //下載進度事件處理程序 private static void _webClient_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e) { Console.WriteLine($"{e.ProgressPercentage}:{e.BytesSent}/{e.TotalBytesToSend}"); }
運行結果如下:
3)文件刪除:
static void Main(string[] args) { //定義_webClient對象 WebClient _webClient = new WebClient(); //使用Windows登錄方式 _webClient.Credentials = new NetworkCredential("test", "123"); //待刪除的文件鏈接地址(文件服務器) Uri _uri = new Uri(@"http://192.168.1.103/test.doc"); //注冊刪除完成時的事件(模擬刪除) _webClient.UploadDataCompleted += _webClient_UploadDataCompleted; //異步從文件(模擬)刪除文件 _webClient.UploadDataAsync(_uri, "DELETE", new byte[0]); Console.ReadKey(); } //刪除完成事件處理程序 private static void _webClient_UploadDataCompleted(object sender, UploadDataCompletedEventArgs e) { Console.WriteLine("Deleted..."); }
運行結果如下:
4)列出文件(或目錄):
需引入命名空間:System.IO、System.Xml及System.Globalization
static void Main(string[] args) { SortedList<string, ServerFileAttributes> _results =GetContents(@"http://192.168.1.103", true); //在控制台輸出文件(或目錄)信息: foreach(var _r in _results) { Console.WriteLine($"{_r.Key}:\r\nName:{_r.Value.Name}\r\nIsFolder:{_r.Value.IsFolder}"); Console.WriteLine($"Value:{_r.Value.Url}\r\nLastModified:{_r.Value.LastModified}"); Console.WriteLine(); } Console.ReadKey(); } //定義每個文件或目錄的屬性 struct ServerFileAttributes { public string Name; public bool IsFolder; public string Url; public DateTime LastModified; } //將文件或目錄列出來 static SortedList<string, ServerFileAttributes> GetContents(string serverUrl, bool deep) { HttpWebRequest _httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(serverUrl); _httpWebRequest.Headers.Add("Translate: f"); _httpWebRequest.Credentials = CredentialCache.DefaultCredentials; string _requestString = @"<?xml version=""1.0"" encoding=""utf-8""?>" + @"<a:propfind xmlns:a=""DAV:"">" + "<a:prop>" + "<a:displayname/>" + "<a:iscollection/>" + "<a:getlastmodified/>" + "</a:prop>" + "</a:propfind>"; _httpWebRequest.Method = "PROPFIND"; if (deep == true) _httpWebRequest.Headers.Add("Depth: infinity"); else _httpWebRequest.Headers.Add("Depth: 1"); _httpWebRequest.ContentLength = _requestString.Length; _httpWebRequest.ContentType = "text/xml"; Stream _requestStream = _httpWebRequest.GetRequestStream(); _requestStream.Write(Encoding.ASCII.GetBytes(_requestString), 0, Encoding.ASCII.GetBytes(_requestString).Length); _requestStream.Close(); HttpWebResponse _httpWebResponse; StreamReader _streamReader; try { _httpWebResponse = (HttpWebResponse)_httpWebRequest.GetResponse(); _streamReader = new StreamReader(_httpWebResponse.GetResponseStream()); } catch (WebException ex) { throw ex; } StringBuilder _stringBuilder = new StringBuilder(); char[] _chars = new char[1024]; int _bytesRead = 0; _bytesRead = _streamReader.Read(_chars, 0, 1024); while (_bytesRead > 0) { _stringBuilder.Append(_chars, 0, _bytesRead); _bytesRead = _streamReader.Read(_chars, 0, 1024); } _streamReader.Close(); XmlDocument _xmlDocument = new XmlDocument(); _xmlDocument.LoadXml(_stringBuilder.ToString()); XmlNamespaceManager _xmlNamespaceManager = new XmlNamespaceManager(_xmlDocument.NameTable); _xmlNamespaceManager.AddNamespace("a", "DAV:"); XmlNodeList _nameList = _xmlDocument.SelectNodes("//a:prop/a:displayname", _xmlNamespaceManager); XmlNodeList _isFolderList = _xmlDocument.SelectNodes("//a:prop/a:iscollection", _xmlNamespaceManager); XmlNodeList _lastModifyList = _xmlDocument.SelectNodes("//a:prop/a:getlastmodified", _xmlNamespaceManager); XmlNodeList _hrefList = _xmlDocument.SelectNodes("//a:href", _xmlNamespaceManager); SortedList<string, ServerFileAttributes> _sortedListResult = new SortedList<string, ServerFileAttributes>(); ServerFileAttributes _serverFileAttributes; for (int i = 0; i < _nameList.Count; i++) { if (_hrefList[i].InnerText.ToLower(new CultureInfo("en-US")).TrimEnd(new char[] { '/' }) != serverUrl.ToLower(new CultureInfo("en-US")).TrimEnd(new char[] { '/' })) { _serverFileAttributes = new ServerFileAttributes(); _serverFileAttributes.Name = _nameList[i].InnerText; _serverFileAttributes.IsFolder = Convert.ToBoolean(Convert.ToInt32(_isFolderList[i].InnerText)); _serverFileAttributes.Url = _hrefList[i].InnerText; _serverFileAttributes.LastModified = Convert.ToDateTime(_lastModifyList[i].InnerText); _sortedListResult.Add(_serverFileAttributes.Url, _serverFileAttributes); } } return _sortedListResult; }
運行結果如下: