說明:1.WebRequest類是一個抽象類,因此上傳類實際使用的是其子類html
2.打開Fiddler軟件,監視正常網頁的文件上傳,能夠看到http協議的請求和響應信息,簡略說明web
(第一行:請求說明app
POST http://localhost/UpLoad.aspx HTTP/1.1 (請求類型:post,請求地址: http://localhost/UpLoad.aspx,http協議類型:HTTP/1.1)post
第二行至多行:請求頭(一系列的 key:value)ui
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Content-Type: multipart/form-data;charset=utf-8;boundary=8D30475B6E5BB4C
Host:localhost
Content-Length: 22194
Expect: 100-continue
Connection: Closespa
換行,第n行:請求體code
響應相似,詳細見fiddler。orm
3.經過查看fiddler監測的http請求過程,能夠利用webrequest模擬http請求,代碼以下:xml
private void UploadFile(string path) { try { if (!string.IsNullOrEmpty(path)) { string filename = Path.GetFileName(path); //獲取文件名稱 LogWrite("上傳文件", "開始上傳文件,文件名稱" + filename, null); string boundary = DateTime.Now.Ticks.ToString("X"); // 隨機分隔線 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost/UpLoad.aspx"); request.ServicePoint.ConnectionLimit = 50; //設置最大鏈接數
request.ServicePoint.Expect100Continue = false;//解決webexception操做超時
request.Method = "POST"; //請求方法 #region ==請求頭=== request.KeepAlive = false; //請求鏈接方式,設置爲請求完成後斷開鏈接 request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0"; request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary; #endregion byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");//分割線數據 byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");//結束分割線數據 StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", filename)); byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString()); //上傳文件頭數據 string sbheader2 = string.Format("Content-Disposition:form-data;name=\"ws\"\r\n\r\nother");//其餘的form表單數據,這裏爲:form["ws"]="other" byte[] ddd = Encoding.UTF8.GetBytes(sbheader2); FileStream fs = new FileStream(path, FileMode.Open);//讀取文件 byte[] bArr = new byte[fs.Length]; long filesize = fs.Length; fs.Read(bArr, 0, (int)filesize); fs.Close(); request.ContentLength = itemBoundaryBytes.Length * 2 + ddd.Length + postHeaderBytes.Length + filesize + endBoundaryBytes.Length;//設置請求長度,必定要設置,不然可能會引起請求超時的異常 Stream sm = request.GetRequestStream(); //獲取請求流 sm.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);//寫入分割線數據 sm.Write(ddd, 0, ddd.Length); //寫入表單數據 sm.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);//寫入分割線數據 sm.Write(postHeaderBytes, 0, postHeaderBytes.Length);//寫入上傳文件頭數據 long size = 0; float percent = 0; //上傳進度 //分步上傳 while (size < filesize) { if (filesize - size > 1024) { sm.Write(bArr, (int)size, 1024); size += 1024; } else { sm.Write(bArr, (int)size, (int)(filesize - size)); size = filesize; } percent = size / (float)filesize; } //sm.Write(bArr, 0, bArr.Length); sm.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); //寫入結束分割線 sm.Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); //獲取響應 Stream sss = response.GetResponseStream(); LogWrite("上傳文件", response.StatusCode.ToString() + filename, null); //Stream sss = request.GetResponse().GetResponseStream(); StreamReader sr = new StreamReader(sss); string ret = sr.ReadToEnd(); sr.Close(); LogWrite("上傳文件", "結束上傳文件,返回結果" + ret, null); //資源釋放 response.Close(); request.Abort(); System.GC.Collect(); } } catch (Exception ex) { LogWrite("上傳文件發生異常", "", ex); } }
4.注意:必定要設置request.ContentLength的大小,不然可能引起操做超時的異常信息。htm