上傳圖片的格式必定要按規定的寫,否則沒辦法正確上傳的。html
我在上傳的時候就是值前面沒有空一行,致使上傳不成功,很糾結的錯誤。web
我要模擬的是一個FLASH的上傳控件,我開始用HttpAnalyze抓包是抓不到的。後來上網搜索到了【抓包工具】Charles v3.6.4,下載安裝後,能夠抓到FLASH上傳時候的包了。緩存
FLASH上傳應該也是POST,可能不是HTTP包,但應該能夠按HTTP的方式發送吧。結果證實個人想法是對的,能夠正常上傳。服務器
FLASH上傳與普通的按鈕上傳控件有什麼區別呢?有待搜索到相關資料。cookie
Charles v3.6.4 下載地址app
原版下載地址: http://www.charlesproxy.com/download/
破解補丁下載地址: http://note.sdo.com/u/1528563206/n/r70o6~jK35opnM10I000fd工具
下面是參考代碼,注意上傳的格式就好。post
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Dictionary<string, string> inputDic=new Dictionary<string,string>(); inputDic.Add("username","westfruit"); inputDic.Add("password","123456"); PostFile("http://avatar.csdn.net/0/1/1/1_zfrong.jpg", "http://www.westfruit.com/news/uppic.asp?strAction=shangchuan", @"D:\1.jpg", "application/octet-stream", inputDic); } #region 下載文件並上傳到指定頁面 /** * 若是要在客戶端向服務器上傳文件,咱們就必須模擬一個POST multipart/form-data類型的請求 * Content-Type必須是multipart/form-data。 * 以multipart/form-data編碼的POST請求格式與application/x-www-form-urlencoded徹底不一樣 * multipart/form-data須要首先在HTTP請求頭設置一個分隔符,例如7d4a6d158c9: * 咱們模擬的提交要設定 content-type不一樣於非含附件的post時候的content-type * 這裏須要: ("Content-Type", "multipart/form-data; boundary=ABCD"); * 而後,將每一個字段用「--7d4a6d158c9」分隔,最後一個「--7d4a6d158c9--」表示結束。 * 例如,要上傳一個title字段"Today"和一個文件C:\1.txt,HTTP正文以下: * * --7d4a6d158c9 * Content-Disposition: form-data; name="title" * \r\n\r\n * Today * --7d4a6d158c9 * Content-Disposition: form-data; name="1.txt"; filename="C:\1.txt" * Content-Type: text/plain * 若是是圖片Content-Type: application/octet-stream * \r\n\r\n * <這裏是1.txt文件的內容> * --7d4a6d158c9 * \r\n * 請注意,每一行都必須以\r\n結束value前面必須有2個\r\n,包括最後一行。 */ /// <summary> /// 下載文件上傳到指定地址 /// </summary> /// <param name="getUrl">文件下載地址</param> /// <param name="postUrl">文件上傳地址</param> /// <param name="fileName">file控件名稱</param> /// <param name="fileType">上傳文件類型</param> /// <param name="inputParamter">其餘表單元素</param> public static void PostFile(string getUrl, string postUrl, string fileName, string fileType, Dictionary<string, string> inputDic) { CredentialCache cache = new CredentialCache();//建立緩存容器 cache.Add(new Uri("http://www.westfruit.com/"), "Basic", new NetworkCredential("westfruit", "7766517")); CookieContainer cookies = new CookieContainer();//建立cookie容器 MemoryStream fileStream = GetFileStream(getUrl);//下載文件返回內存流 // cast the WebRequest to a HttpWebRequest since we're using HTTPS string boundary = "----------" + DateTime.Now.Ticks.ToString("x");//元素分割標記 HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(postUrl); httpWebRequest2.Credentials = cache; httpWebRequest2.CookieContainer = cookies; httpWebRequest2.ContentType = "multipart/form-data; boundary=" + boundary;//其餘地方的boundary要比這裏多-- httpWebRequest2.Method = "POST";//Post請求方式 // Build up the post message 拼接建立表單內容 StringBuilder sb = new StringBuilder(); //拼接非文件表單控件 //遍歷字典取出表單普通空間的健和值 foreach (KeyValuePair<string, string> dicItem in inputDic) { sb.Append("--" + boundary); sb.Append("\r\n"); sb.Append("Content-Disposition: form-data; name=\"" + dicItem.Key + "\""); sb.Append("\r\n"); sb.Append("\r\n"); sb.Append(dicItem.Value);//value前面必須有2個換行 sb.Append("\r\n"); } //拼接文件控件 sb.Append("--"+boundary); sb.Append("\r\n"); sb.Append("Content-Disposition: form-data; name=\"file1\"; filename=\"C:\\upload" + Path.GetFileName(fileName) + "\""); sb.Append("\r\n"); sb.Append("Content-Type: application/octet-stream"); sb.Append("\r\n"); sb.Append("\r\n");//value前面必須有2個換行 byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sb.ToString()); // Build the trailing boundary string as a byte array 建立結束標記 // ensuring the boundary appears on a line by itself byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); //http請求總長度 httpWebRequest2.ContentLength = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length; Stream requestStream = httpWebRequest2.GetRequestStream(); //定義一個http請求流 // Write out our post header 將開始標記寫入流 requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length); // Write out the file contents 將附件寫入流,最大4M byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))]; int bytesRead = 0; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) requestStream.Write(buffer, 0, bytesRead); fileStream.Dispose(); // Write out the trailing boundary 將結束標記寫入流 requestStream.Write(boundaryBytes, 0, boundaryBytes.Length); //Send http request back WebResponse 發送http請求 WebResponse webResponse2 = httpWebRequest2.GetResponse(); //從WebResponse中解析出html代碼開始 Stream htmlStream = webResponse2.GetResponseStream(); string HTML = GetHtml(htmlStream, "UTF-8"); htmlStream.Dispose(); //從WebResponse中解析出html代碼結束 } #endregion #region 下載文件 /// <summary> /// 從互聯網下載文件 /// </summary> /// <param name="getUrl">文件地址</param> /// <returns>內存流</returns> public static MemoryStream GetFileStream(string getUrl) { MemoryStream fileStream;//定義一個內存流保存接收到的文件流 HttpWebRequest httpWebRequest1 = (HttpWebRequest)WebRequest.Create(getUrl); WebResponse webResponse1 = httpWebRequest1.GetResponse(); byte[] buffer1 = new byte[4096];//定義一個4M大小的數字 Stream stream1 = webResponse1.GetResponseStream();//定義一個流接受html返回的文件流 fileStream = new MemoryStream();//stream1不支持查找操做因此將其轉入內存流 int l; do { l = stream1.Read(buffer1, 0, buffer1.Length); if (l > 0) { fileStream.Write(buffer1, 0, l);//將文件流按字節寫入內存流 } } while (l > 0); stream1.Close(); fileStream.Position = 0; return fileStream; } #endregion #region 解析html代碼 /// <summary> /// 從html流中解析出html代碼 /// </summary> /// <param name="htmlStream">html流</param> /// <param name="Encoding">編碼格式</param> /// <returns>html</returns> public static string GetHtml(Stream htmlStream, string Encoding) { StreamReader objReader = new StreamReader(htmlStream, System.Text.Encoding.GetEncoding(Encoding)); string HTML = ""; string sLine = ""; int i = 0; while (sLine != null) { i++; sLine = objReader.ReadLine(); if (sLine != null) HTML += sLine; } HTML = HTML.Replace("<", "<"); HTML = HTML.Replace(">", ">"); objReader.Dispose(); return HTML; } #endregion } }