HttpWebRequest類與HttpRequest類的區別。html
HttpRequest類的對象用於服務器端,獲取客戶端傳來的請求的信息,包括HTTP報文傳送過來的全部信息。而HttpWebRequest用於客戶端,拼接請求的HTTP報文併發送等。web
HttpWebRequest這個類很是強大,強大的地方在於它封裝了幾乎HTTP請求報文裏須要用到的東西,以至於可以可以發送任意的HTTP請求並得到服務器響應(Response)信息。採集信息經常使用到這個類。在學習這個類以前,首先有必要了解下HTTP方面的知識。服務器
咱們先來一個最簡單的,就是牢牢輸入一個網址就獲取響應。代碼以下:cookie
class Program { static void Main(string[] args) { HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://www.baidu.com"); //建立一個請求示例 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); //獲取響應,即發送請求 Stream responseStream = response.GetResponseStream(); StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); string html = streamReader.ReadToEnd(); Console.WriteLine(html); Console.ReadKey(); } }
OK,就是這麼簡單了,真的這麼簡單嗎?發送一個HTTP請求真的這麼簡單。可是要作出不少功能就不簡單了。你須要詳細瞭解下HTTP方面的知識,好比HTTP請求報文之類的。併發
下面來個複雜點的,此次是獲取登陸以後的頁面。登陸以後的請求用什麼實現呢?呵呵,用到是cookie。在拼接HTTP請求的時候,連着cookie也發送過去。app
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { HttpHeader header = new HttpHeader(); header.accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight-2-b1, */*"; header.contentType = "application/x-www-form-urlencoded"; header.method = "POST"; header.userAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"; header.maxTry = 300; //在這裏本身拼接一下Cookie,不用複製過來的那個GetCookie方法了,原來的那個寫法仍是比較嚴謹的 CookieContainer cc = new CookieContainer(); Cookie cUserName = new Cookie("cSpaceUserEmail", "742783833%40qq.com"); cUserName.Domain = ".7soyo.com"; Cookie cUserPassword = new Cookie("cSpaceUserPassWord", "4f270b36a4d3e5ee70b65b1778e8f793"); cUserPassword.Domain = ".7soyo.com"; cc.Add(cUserName); cc.Add(cUserPassword); string html = HTMLHelper.GetHtml("http://user.7soyo.com/CollectUser/List", cc, header); FileStream fs = new FileStream(@"D:\123.txt",FileMode.CreateNew,FileAccess.ReadWrite); fs.Write(Encoding.UTF8.GetBytes(html),0,html.Length); fs.Flush(); fs.Dispose(); Console.WriteLine(html); Console.ReadKey(); } } public class HTMLHelper { /// <summary> /// 獲取CooKie /// </summary> /// <param name="loginUrl"></param> /// <param name="postdata"></param> /// <param name="header"></param> /// <returns></returns> public static CookieContainer GetCooKie(string loginUrl, string postdata, HttpHeader header) { HttpWebRequest request = null; HttpWebResponse response = null; try { CookieContainer cc = new CookieContainer(); request = (HttpWebRequest)WebRequest.Create(loginUrl); request.Method = header.method; request.ContentType = header.contentType; byte[] postdatabyte = Encoding.UTF8.GetBytes(postdata); //提交的請求主體的內容 request.ContentLength = postdatabyte.Length; //提交的請求主體的長度 request.AllowAutoRedirect = false; request.CookieContainer = cc; request.KeepAlive = true; //提交請求 Stream stream; stream = request.GetRequestStream(); stream.Write(postdatabyte, 0, postdatabyte.Length); //帶上請求主體 stream.Close(); //接收響應 response = (HttpWebResponse)request.GetResponse(); //正式發起請求 response.Cookies = request.CookieContainer.GetCookies(request.RequestUri); CookieCollection cook = response.Cookies; //Cookie字符串格式 string strcrook = request.CookieContainer.GetCookieHeader(request.RequestUri); return cc; } catch (Exception ex) { throw ex; } } /// <summary> /// 獲取html /// </summary> /// <param name="getUrl"></param> /// <param name="cookieContainer"></param> /// <param name="header"></param> /// <returns></returns> public static string GetHtml(string getUrl, CookieContainer cookieContainer, HttpHeader header) { Thread.Sleep(1000); HttpWebRequest httpWebRequest = null; HttpWebResponse httpWebResponse = null; try { httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(getUrl); httpWebRequest.CookieContainer = cookieContainer; httpWebRequest.ContentType = header.contentType; httpWebRequest.ServicePoint.ConnectionLimit = header.maxTry; httpWebRequest.Referer = getUrl; httpWebRequest.Accept = header.accept; httpWebRequest.UserAgent = header.userAgent; httpWebRequest.Method = "GET"; httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); Stream responseStream = httpWebResponse.GetResponseStream(); StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); string html = streamReader.ReadToEnd(); streamReader.Close(); responseStream.Close(); httpWebRequest.Abort(); httpWebResponse.Close(); return html; } catch (Exception e) { if (httpWebRequest != null) httpWebRequest.Abort(); if (httpWebResponse != null) httpWebResponse.Close(); return string.Empty; } } } public class HttpHeader { public string contentType { get; set; } public string accept { get; set; } public string userAgent { get; set; } public string method { get; set; } public int maxTry { get; set; } } }
這樣獲取到的就是登陸以後的頁面了。post
再來一個例子,運用HttpWebRequest來模擬表單的提交,先新建一個MVC項目,裏面只有這些代碼:學習
[HttpPost] public ActionResult Index(string userName,string userPassword) { string str = "你提交過來的用戶名是:" + userName + ",密碼是: " + userPassword; Response.Write(str); return View(); }
而後啓動該項目,再新建另一個項目,用於模擬提交表單,而後注意路徑填寫的是剛纔建的那個MVC項目。測試
static void Main(string[] args) { HttpWebRequest request = null; HttpWebResponse response = null; CookieContainer cc = new CookieContainer(); request = (HttpWebRequest)WebRequest.Create("http://localhost:2539/"); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0"; string requestForm = "userName=1693372175&userPassword=123456"; //拼接Form表單裏的信息 byte[] postdatabyte = Encoding.UTF8.GetBytes(requestForm); request.ContentLength = postdatabyte.Length; request.AllowAutoRedirect = false; request.CookieContainer = cc; request.KeepAlive = true; Stream stream; stream = request.GetRequestStream(); stream.Write(postdatabyte, 0, postdatabyte.Length); //設置請求主體的內容 stream.Close(); //接收響應 response = (HttpWebResponse)request.GetResponse(); Console.WriteLine(); Stream stream1 = response.GetResponseStream(); StreamReader sr = new StreamReader(stream1); Console.WriteLine(sr.ReadToEnd()); Console.ReadKey(); }
輸出結果以下所示:ui
血的教訓,注意路徑不能寫錯,不然在對流進行操做時,Write,就會報錯:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:9170/upload/test");
客戶端:
class Program { /** * 若是要在客戶端向服務器上傳文件,咱們就必須模擬一個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,包括最後一行。 */ static void Main(string[] args) { string boundary = "----------" + DateTime.Now.Ticks.ToString("x");//元素分割標記 StringBuilder sb = new StringBuilder(); sb.Append("--" + boundary); sb.Append("\r\n"); sb.Append("Content-Disposition: form-data; name=\"file1\"; filename=\"D:\\upload.xml" + "\""); sb.Append("\r\n"); sb.Append("Content-Type: application/octet-stream"); sb.Append("\r\n"); sb.Append("\r\n");//value前面必須有2個換行 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:9170/upload/test"); request.ContentType = "multipart/form-data; boundary=" + boundary;//其餘地方的boundary要比這裏多-- request.Method = "POST"; FileStream fileStream = new FileStream(@"D:\123.xml", FileMode.OpenOrCreate, FileAccess.Read); byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sb.ToString()); byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); //http請求總長度 request.ContentLength = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length; Stream requestStream = request.GetRequestStream(); requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length); 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(); requestStream.Write(boundaryBytes, 0, boundaryBytes.Length); WebResponse webResponse2 = request.GetResponse(); Stream htmlStream = webResponse2.GetResponseStream(); string HTML = GetHtml(htmlStream, "UTF-8"); Console.WriteLine(HTML); htmlStream.Dispose(); } }
測試服務器端地址:
public ActionResult Test() { HttpRequest request = System.Web.HttpContext.Current.Request; HttpFileCollection FileCollect = request.Files; if (FileCollect.Count > 0) //若是集合的數量大於0 { foreach (string str in FileCollect) { HttpPostedFile FileSave = FileCollect[str]; //用key獲取單個文件對象HttpPostedFile string imgName = DateTime.Now.ToString("yyyyMMddhhmmss"); string AbsolutePath = FileSave.FileName; FileSave.SaveAs(AbsolutePath); //將上傳的東西保存 } } return Content("鍵值對數目:" + FileCollect.Count); }