系列目錄???? 【已更新最新開發(fā)文章,點擊查看詳細】
<https://www.cnblogs.com/SavionZhang/p/11422481.html>
學習本篇之前,對 HttpWebRequest 與 HttpWebResponse 不太熟悉的同學,請先學習《C# HTTP系列》。
應用程序中使用HTTP協(xié)議和服務器交互主要是進行數(shù)據(jù)的上傳與下載,最常見的方式是通過 GET 和 POST 兩種方式來完成。本篇介紹 C#
HttpWebRequest 如何使用這兩種方式來實現(xiàn)。
示例場景:
1 <form id="form1" runat="server" action="UserManageHandler.ashx" method="post"
enctype="application/x-www-form-urlencoded"> 2 <div> 3 名稱: <input type="text"
name="uname" class="uname" /><br /> 4 郵件: <input type="text" name="email" class
="email" /><br /> 5 <input type="submit" name="submit" value="提交" /> 6 </div> 7
</form>
1 using System; 2 using System.Web; 3 4 namespace
SparkSoft.Platform.UI.WebForm.Test 5 { 6 public class UserManageHandler :
IHttpHandler 7 { 8 9 public void ProcessRequest(HttpContext context) 10 { 11
context.Response.ContentType ="text/plain"; 12 13 string uname =
context.Request["uname"]; 14 string email = context.Request["email"]; 15 16
context.Response.Write("提交結(jié)果如下:" + Environment.NewLine + 17 "名稱:" + uname +
Environment.NewLine +18 "郵箱:" + email); 19 } 20 21 public bool IsReusable 22 {
23 get { return false; } 24 } 25 } 26 } 01 HttpWebRequest 提交數(shù)據(jù)方式1 GET方式 GET
方式通過在網(wǎng)絡地址附加參數(shù)來完成數(shù)據(jù)的提交,
比如在地址?http://localhost:5000/Test/UserManageHandler.ashx?uname=zhangsan?中,前面部分?http://localhost:5000/Test/UserManageHandler.ashx
表示數(shù)據(jù)提交的網(wǎng)址,后面部分?uname=zhangsan 表示附加的參數(shù),其中uname 表示一個鍵(key),?zhangsan
表示這個鍵對應的值(value)。程序代碼如下: 1 /// <summary> 2 /// 普通 GET 方式請求 3 /// </summary>
4 public void Request01_ByGet() 5 { 6 HttpWebRequest httpWebRequest =
WebRequest.Create("
http://localhost:5000/Test/UserManageHandler.ashx?uname=zhangsan") as
HttpWebRequest; 7 httpWebRequest.Method = "GET"; 8 9 HttpWebResponse
httpWebResponse = httpWebRequest.GetResponse()as HttpWebResponse; // 獲取響應 10 if
(httpWebResponse !=null) 11 { 12 using (StreamReader sr = new
StreamReader(httpWebResponse.GetResponseStream()))13 { 14 string content =
sr.ReadToEnd();15 } 16 17 httpWebResponse.Close(); 18 } 19 } 02
HttpWebRequest 提交數(shù)據(jù)方式2 POST方式 POST 方式通過在頁面內(nèi)容中填寫參數(shù)的方法來完成數(shù)據(jù)的提交,
?參數(shù)的格式和 GET 方式一樣,是類似于 [email protected] 這樣的結(jié)構(gòu)。程序代碼如下:
1 /// <summary> 2 /// 普通 POST 方式請求 3 /// </summary> 4 public void
Request02_ByPost() 5 { 6 string param = "[email protected]";
//參數(shù) 7 byte[] paramBytes = Encoding.ASCII.GetBytes(param); //參數(shù)轉(zhuǎn)化為 ASCII 碼 8
9 HttpWebRequest httpWebRequest = WebRequest.Create("
http://localhost:5000/Test/UserManageHandler.ashx") as HttpWebRequest; 10
httpWebRequest.Method ="POST"; 11 httpWebRequest.ContentType = "
application/x-www-form-urlencoded"; 12 httpWebRequest.ContentLength =
paramBytes.Length;13 14 using (Stream reqStream =
httpWebRequest.GetRequestStream())15 { 16 reqStream.Write(paramBytes, 0,
paramBytes.Length);17 } 18 19 HttpWebResponse httpWebResponse =
httpWebRequest.GetResponse()as HttpWebResponse; // 獲取響應 20 if (httpWebResponse
!=null) 21 { 22 using (StreamReader sr = new
StreamReader(httpWebResponse.GetResponseStream()))23 { 24 string content =
sr.ReadToEnd();25 } 26 27 httpWebResponse.Close(); 28 } 29 }
如果提交的請求參數(shù)中包含中文,那么需要對其進行編碼,讓目標網(wǎng)站能夠識別。
03 HttpWebRequest 提交數(shù)據(jù)方式3 GET方式提交中文數(shù)據(jù) GET 方式通過在網(wǎng)絡地址中附加參數(shù)來完成數(shù)據(jù)提交,對于中文的編碼,常用的有
gb2312 和 utf-8 兩種。下面以 gb2312 方式編碼來說明,程序代碼如下: 1 /// <summary> 2 /// 使用 GET
方式提交中文數(shù)據(jù) 3 /// </summary> 4 public void Request03_ByGet() 5 { 6 /*GET
方式通過在網(wǎng)絡地址中附加參數(shù)來完成數(shù)據(jù)提交,對于中文的編碼,常用的有 gb2312 和 utf8 兩種。 7 *
由于無法告知對方提交數(shù)據(jù)的編碼類型,所以編碼方式要以對方的網(wǎng)站為標準。 8 * 常見的網(wǎng)站中, www.baidu.com (百度)的編碼方式是
gb2312, www.google.com (谷歌)的編碼方式是 utf8。 9 */ 10 Encoding myEncoding =
Encoding.GetEncoding("gb2312"); //確定用哪種中文編碼方式 11 string address = "
http://www.baidu.com/s?" + HttpUtility.UrlEncode("參數(shù)一", myEncoding) + "=" +
HttpUtility.UrlEncode("值一", myEncoding); //拼接數(shù)據(jù)提交的網(wǎng)址和經(jīng)過中文編碼后的中文參數(shù) 12 13
HttpWebRequest httpWebRequest = WebRequest.Create(address)as HttpWebRequest; 14
httpWebRequest.Method ="GET"; 15 16 HttpWebResponse httpWebResponse =
httpWebRequest.GetResponse()as HttpWebResponse; // 獲取響應 17 if (httpWebResponse
!=null) 18 { 19 using (StreamReader sr = new
StreamReader(httpWebResponse.GetResponseStream()))20 { 21 string content =
sr.ReadToEnd();22 } 23 24 httpWebResponse.Close(); 25 } 26 }
在上面的程序代碼中,我們以 GET 方式訪問了網(wǎng)址 http://www.baidu.com/s
,傳遞了參數(shù)“參數(shù)一=值一”,由于無法告知對方提交數(shù)據(jù)的編碼類型,所以編碼方式要以對方的網(wǎng)站為標準。常見的網(wǎng)站中, www.baidu.com
(百度)的編碼方式是 gb2312, www.google.com (谷歌)的編碼方式是 utf-8。
04 HttpWebRequest 提交數(shù)據(jù)方式4 POST方式提交中文數(shù)據(jù) POST
方式通過在頁面內(nèi)容中填寫參數(shù)的方法來完成數(shù)據(jù)的提交,由于提交的參數(shù)中可以說明使用的編碼方式,所以理論上能獲得更大的兼容性。下面以 gb2312
方式編碼來說明,程序代碼如下: /// <summary> /// 使用 POST 方式提交中文數(shù)據(jù) /// </summary> public void
Request04_ByPost() {/* POST
方式通過在頁面內(nèi)容中填寫參數(shù)的方法來完成數(shù)據(jù)的提交,由于提交的參數(shù)中可以說明使用的編碼方式,所以理論上能獲得更大的兼容性。*/ Encoding
myEncoding= Encoding.GetEncoding("gb2312"); //確定用哪種中文編碼方式 string param =
HttpUtility.UrlEncode("參數(shù)一", myEncoding) + "=" + HttpUtility.UrlEncode("值一",
myEncoding) +"&" + HttpUtility.UrlEncode("參數(shù)二", myEncoding) + "=" +
HttpUtility.UrlEncode("值二", myEncoding); byte[] paramBytes =
Encoding.ASCII.GetBytes(param);//參數(shù)轉(zhuǎn)化為 ASCII 碼 HttpWebRequest httpWebRequest =
WebRequest.Create("https://www.baidu.com/") as HttpWebRequest;
httpWebRequest.Method= "POST"; httpWebRequest.ContentType = "
application/x-www-form-urlencoded;charset=gb2312"; httpWebRequest.ContentLength
= paramBytes.Length; using (Stream reqStream =
httpWebRequest.GetRequestStream()) { reqStream.Write(paramBytes,0,
paramBytes.Length); } HttpWebResponse httpWebResponse=
httpWebRequest.GetResponse()as HttpWebResponse; // 獲取響應 if (httpWebResponse !=
null) { using (StreamReader sr = new
StreamReader(httpWebResponse.GetResponseStream())) {string content =
sr.ReadToEnd(); } httpWebResponse.Close(); } }
以上列出了客戶端程序使用HTTP協(xié)議與服務器交互的情況,常用的是 GET 和 POST 方式?,F(xiàn)在流行的?WebService 也是通過 HTTP
協(xié)議來交互的,使用的是?POST 方法。與以上稍有所不同的是,?WebService 提交的數(shù)據(jù)內(nèi)容和接收到的數(shù)據(jù)內(nèi)容都是使用了 XML 方式編碼。所以,
HttpWebRequest 也可以使用在調(diào)用 WebService 的場景下。
HttpWebRequest 請求通用方法 (不包含body數(shù)據(jù))POST、GET請求 1 /// <summary> 2 ///
HTTP-GET方法,(不包含body數(shù)據(jù))。 3 /// 發(fā)送 HTTP 請求并返回來自 Internet 資源的響應(HTML代碼) 4 ///
</summary> 5 /// <param name="url">請求目標URL</param> 6 /// <returns>
HTTP-GET的響應結(jié)果</returns> 7 public HttpResult Get(string url) 8 { 9 return
Request(url, WebRequestMethods.Http.Get);10 } 1 /// <summary> 2 ///
HTTP-POST方法,(不包含body數(shù)據(jù))。 3 /// 發(fā)送 HTTP 請求并返回來自 Internet 資源的響應(HTML代碼) 4 ///
</summary> 5 /// <param name="url">請求目標URL</param> 6 /// <returns>
HTTP-POST的響應結(jié)果</returns> 7 public HttpResult Post(string url) 8 { 9 return
Request(url, WebRequestMethods.Http.Post);10 } (包含文本的body數(shù)據(jù))請求
1 /// <summary> 2 /// HTTP請求(包含JSON文本的body數(shù)據(jù)) 3 /// </summary> 4 ///
<param name="url">請求目標URL</param> 5 /// <param name="data">
主體數(shù)據(jù)(JSON文本)。如果參數(shù)中有中文,請使用合適的編碼方式進行編碼,例如:gb2312或者utf-8</param> 6 /// <param
name="method">請求的方法。請使用 WebRequestMethods.Http 的枚舉值</param> 7 ///
<returns></returns> 8 public HttpResult UploadJson(string url, string data,
string method = WebRequestMethods.Http.Post) 9 { 10 return Request(url, data,
method, HttpContentType.APPLICATION_JSON);11 } 1 /// <summary> 2 ///
HTTP請求(包含普通文本的body數(shù)據(jù)) 3 /// </summary> 4 /// <param name="url">請求目標URL</param>
5 /// <param name="data">主體數(shù)據(jù)(普通文本)。如果參數(shù)中有中文,請使用合適的編碼方式進行編碼,例如:gb2312或者utf-8
</param> 6 /// <param name="method">請求的方法。請使用 WebRequestMethods.Http 的枚舉值
</param> 7 /// <returns></returns> 8 public HttpResult UploadText(string url,
string data, string method = WebRequestMethods.Http.Post) 9 { 10 return
Request(url, data, method, HttpContentType.TEXT_PLAIN);11 }
上面的4個方法調(diào)用了公用的業(yè)務方法,分別如下:
1 /// <summary> 2 /// HTTP請求,(不包含body數(shù)據(jù))。 3 /// 發(fā)送 HTTP 請求并返回來自 Internet
資源的響應(HTML代碼) 4 /// </summary> 5 /// <param name="url">請求目標URL</param> 6 ///
<param name="method">請求的方法。請使用 WebRequestMethods.Http 的枚舉值</param> 7 ///
<returns>HTTP的響應結(jié)果</returns> 8 private HttpResult Request(string url, string
method) 9 { 10 HttpResult httpResult = new HttpResult(); 11 HttpWebRequest
httpWebRequest =null; 12 try 13 { 14 httpWebRequest = WebRequest.Create(url) as
HttpWebRequest;15 httpWebRequest.Method = method; 16 httpWebRequest.UserAgent =
_userAgent;17 httpWebRequest.AllowAutoRedirect = _allowAutoRedirect; 18
httpWebRequest.ServicePoint.Expect100Continue =false; 19 20 HttpWebResponse
httpWebResponse = httpWebRequest.GetResponse()as HttpWebResponse; 21 if
(httpWebResponse !=null) 22 { 23 GetResponse(ref httpResult, httpWebResponse);
24 httpWebResponse.Close(); 25 } 26 } 27 catch (WebException webException) 28
{29 GetWebExceptionResponse(ref httpResult, webException); 30 } 31 catch
(Exception ex)32 { 33 GetExceptionResponse(ref httpResult, ex, method, string
.Empty);34 } 35 finally 36 { 37 if (httpWebRequest != null) 38 { 39
httpWebRequest.Abort();40 } 41 } 42 43 return httpResult; 44 } 1 ///
<summary> 2 /// HTTP請求(包含文本的body數(shù)據(jù)) 3 /// </summary> 4 /// <param name="url">
請求目標URL</param> 5 /// <param name="data">
主體數(shù)據(jù)(普通文本或者JSON文本)。如果參數(shù)中有中文,請使用合適的編碼方式進行編碼,例如:gb2312或者utf-8</param> 6 ///
<param name="method">請求的方法。請使用 WebRequestMethods.Http 的枚舉值</param> 7 ///
<param name="contentType"><see langword="Content-type" /> HTTP 標頭的值。請使用
ContentType 類的常量來獲取</param> 8 /// <returns></returns> 9 private HttpResult
Request(string url, string data, string method, string contentType) 10 { 11
HttpResult httpResult =new HttpResult(); 12 HttpWebRequest httpWebRequest = null
;13 14 try 15 { 16 httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
17 httpWebRequest.Method = method; 18 httpWebRequest.Headers = HeaderCollection;
19 httpWebRequest.CookieContainer = CookieContainer; 20
httpWebRequest.ContentType = contentType;//
此屬性的值存儲在WebHeaderCollection中。如果設置了WebHeaderCollection,則屬性值將丟失。所以放置在Headers
屬性之后設置 21 httpWebRequest.UserAgent = _userAgent; 22
httpWebRequest.AllowAutoRedirect = _allowAutoRedirect; 23
httpWebRequest.ServicePoint.Expect100Continue =false; 24 25 if (data != null) 26
{27 httpWebRequest.AllowWriteStreamBuffering = true; 28 using (Stream
requestStream = httpWebRequest.GetRequestStream()) 29 { 30
requestStream.Write(EncodingType.GetBytes(data),0, data.Length);//將請求參數(shù)寫入請求流中 31
requestStream.Flush();32 } 33 } 34 35 HttpWebResponse httpWebResponse =
httpWebRequest.GetResponse()as HttpWebResponse; 36 if (httpWebResponse != null)
37 { 38 GetResponse(ref httpResult, httpWebResponse); 39
httpWebResponse.Close();40 } 41 } 42 catch (WebException webException) 43 {
44 GetWebExceptionResponse(ref httpResult, webException); 45 } 46 catch
(Exception ex)47 { 48 GetExceptionResponse(ref httpResult, ex, method,
contentType);49 } 50 finally 51 { 52 if (httpWebRequest != null) 53 { 54
httpWebRequest.Abort();55 } 56 } 57 58 return httpResult; 59 }
其中2個Request方法中用到了其他的封裝類,比如:HttpResult
1 /// <summary> 2 /// HTTP請求(GET,POST等)的響應返回消息 3 /// </summary> 4 public
sealed class HttpResult 5 { 6 #region 字段 7 8 /// <summary> 9 /// HTTP
響應成功,即狀態(tài)碼為200 10 /// </summary> 11 public const string STATUS_SUCCESS = "
success"; 12 13 /// <summary> 14 /// HTTP 響應失敗 15 /// </summary> 16 public
const string STATUS_FAIL = "fail"; 17 18 #endregion 19 20 #region 屬性 21 22
/// <summary> 23 /// 獲取或設置請求的響應狀態(tài),success 或者
fail。建議使用常量:HttpResult.STATUS_SUCCESS 與 HttpResult.STATUS_FAIL 24 /// </summary>
25 public string Status { get; set; } 26 27 /// <summary> 28 ///
獲取或設置請求的響應狀態(tài)描述 29 /// </summary> 30 public string StatusDescription { get; set
; } 31 32 /// <summary> 33 /// 狀態(tài)碼。與 HttpWebResponse.StatusCode 完全相同 34 ///
</summary> 35 public int? StatusCode { get; set; } 36 37 /// <summary> 38
/// 響應消息或錯誤文本 39 /// </summary> 40 public string Text { get; set; } 41 42
/// <summary> 43 /// 響應消息或錯誤(二進制格式) 44 /// </summary> 45 public byte[] Data {
get; set; } 46 47 /// <summary> 48 /// 參考代碼(用戶自定義)。 49 /// 當 Status 等于
success 時,該值為 null; 50 /// 當 Status 等于 fail 時,該值為程序給出的用戶自定義編碼。 51 ///
</summary> 52 public int? RefCode { get; set; } 53 54 /// <summary> 55 ///
附加信息(用戶自定義內(nèi)容,如Exception內(nèi)容或者自定義提示信息)。 56 /// 當 Status 等于 success 時,該值為為空 57 ///
當 Status 等于 fail 時,該值為程序給出的用戶自定義內(nèi)容,如Exception內(nèi)容或者自定義提示信息。 58 /// </summary> 59
public string RefText { get; set; } 60 61 /// <summary> 62 ///
獲取或設置Http的請求響應。 63 /// </summary> 64 public HttpWebResponse HttpWebResponse {
get; set; } 65 66 ///// <summary> 67 ///// 參考信息(從返回消息 WebResponse 的頭部獲取) 68
///// </summary> 69 //public Dictionary<string, string> RefInfo { get; set; }
70 71 #endregion 72 73 #region 構(gòu)造函數(shù) 74 /// <summary> 75 ///
初始化(所有成員默認值,需要后續(xù)賦值) 76 /// </summary> 77 public HttpResult() 78 { 79 Status
=string.Empty; 80 StatusDescription = string.Empty; 81 StatusCode = null; 82
Text =string.Empty; 83 Data = null; 84 85 RefCode = null; 86 RefText =
string.Empty; 87 //RefInfo = null; 88 89 HttpWebResponse = null; 90 } 91
92 #endregion 93 94 #region 方法 95 96 /// <summary> 97 /// 對象復制 98 ///
</summary> 99 /// <param name="httpResultSource">要復制其內(nèi)容的來源</param> 100 public
void Shadow(HttpResult httpResultSource) 101 { 102 this.Status =
httpResultSource.Status;103 this.StatusDescription = string.Empty; 104 this
.StatusCode = httpResultSource.StatusCode; 105 this.Text =
httpResultSource.Text;106 this.Data = httpResultSource.Data; 107 108 this
.RefCode = httpResultSource.RefCode; 109 this.RefText +=
httpResultSource.RefText;110 //this.RefInfo = httpResultSource.RefInfo; 111 112
this.HttpWebResponse = httpResultSource.HttpWebResponse; 113 } 114 115 ///
<summary> 116 /// 轉(zhuǎn)換為易讀或便于打印的字符串格式 117 /// </summary> 118 /// <returns>
便于打印和閱讀的字符串</returns> 119 public override string ToString() 120 { 121
StringBuilder sb =new StringBuilder(); 122 123 sb.AppendFormat("Status:{0}",
Status);124 sb.AppendFormat("StatusCode:{0}", StatusCode); 125 sb.AppendFormat("
StatusDescription:{0}", StatusDescription); 126 sb.AppendLine(); 127 128 if (!
string.IsNullOrEmpty(Text)) 129 { 130 sb.AppendLine("text:"); 131
sb.AppendLine(Text);132 } 133 134 if (Data != null) 135 { 136 sb.AppendLine("
data:"); 137 int n = 1024; 138 if (Data.Length <= n) 139 { 140
sb.AppendLine(Encoding.UTF8.GetString(Data));141 } 142 else 143 { 144
sb.AppendLine(Encoding.UTF8.GetString(Data,0, n)); 145 sb.AppendFormat("<---
TOO-LARGE-TO-DISPLAY --- TOTAL {0} BYTES --->", Data.Length); 146
sb.AppendLine();147 } 148 } 149 150 sb.AppendLine(); 151 152 sb.AppendFormat(
"ref-code:{0}", RefCode); 153 sb.AppendLine(); 154 155 if (!string
.IsNullOrEmpty(RefText))156 { 157 sb.AppendLine("ref-text:"); 158
sb.AppendLine(RefText);159 } 160 161 sb.AppendLine(); 162 163 return
sb.ToString();164 } 165 166 #endregion 167 } View Code
?
系列目錄???? 【已更新最新開發(fā)文章,點擊查看詳細】
<https://www.cnblogs.com/SavionZhang/p/11422481.html>
熱門工具 換一換