系列目录     【已更新最新开发文章,点击查看详细】
<https://www.cnblogs.com/SavionZhang/p/11422481.html>
学习本篇之前,对 HttpWebRequest 与 HttpWebResponse 不太熟悉的同学,请先学习《C# HTTP系列》。

应用程序中使用HTTP协议和服务器交互主要是进行数据的上传与下载,最常见的方式是通过 GET 和 POST 两种方式来完成。本篇介绍 C#
HttpWebRequest 如何使用这两种方式来实现。

示例场景:
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("提交结果如下:" + Environment.NewLine + 17 "名称:" + uname +
Environment.NewLine +18 "邮箱:" + email); 19 } 20 21 public bool IsReusable 22 {
23 get { return false; } 24 } 25 } 26 } 01 HttpWebRequest 提交数据方式1 GET方式 GET
方式通过在网络地址附加参数来完成数据的提交,
比如在地址 http://localhost:5000/Test/UserManageHandler.ashx?uname=zhangsan 中,前面部分 http://localhost:5000/Test/UserManageHandler.ashx
表示数据提交的网址,后面部分 uname=zhangsan 表示附加的参数,其中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 提交数据方式2 POST方式 POST 方式通过在页面内容中填写参数的方法来完成数据的提交,
 参数的格式和 GET 方式一样,是类似于 uname=zhangsan&email=123456@qq.com 这样的结构。程序代码如下:
1 /// <summary> 2 /// 普通 POST 方式请求 3 /// </summary> 4 public void
Request02_ByPost() 5 { 6 string param = "uname=zhangsan&email=123456@qq.com";
//参数 7 byte[] paramBytes = Encoding.ASCII.GetBytes(param); //参数转化为 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 }
如果提交的请求参数中包含中文,那么需要对其进行编码,让目标网站能够识别。
03 HttpWebRequest 提交数据方式3 GET方式提交中文数据 GET 方式通过在网络地址中附加参数来完成数据提交,对于中文的编码,常用的有
gb2312 和 utf-8 两种。下面以 gb2312 方式编码来说明,程序代码如下: 1 /// <summary> 2 /// 使用 GET
方式提交中文数据 3 /// </summary> 4 public void Request03_ByGet() 5 { 6 /*GET
方式通过在网络地址中附加参数来完成数据提交,对于中文的编码,常用的有 gb2312 和 utf8 两种。 7 *
由于无法告知对方提交数据的编码类型,所以编码方式要以对方的网站为标准。 8 * 常见的网站中, 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("参数一", myEncoding) + "=" +
HttpUtility.UrlEncode("值一", myEncoding); //拼接数据提交的网址和经过中文编码后的中文参数 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 方式访问了网址 http://www.baidu.com/s
,传递了参数“参数一=值一”,由于无法告知对方提交数据的编码类型,所以编码方式要以对方的网站为标准。常见的网站中, www.baidu.com
(百度)的编码方式是 gb2312, www.google.com (谷歌)的编码方式是 utf-8。
04 HttpWebRequest 提交数据方式4 POST方式提交中文数据 POST
方式通过在页面内容中填写参数的方法来完成数据的提交,由于提交的参数中可以说明使用的编码方式,所以理论上能获得更大的兼容性。下面以 gb2312
方式编码来说明,程序代码如下: /// <summary> /// 使用 POST 方式提交中文数据 /// </summary> public void
Request04_ByPost() {/* POST
方式通过在页面内容中填写参数的方法来完成数据的提交,由于提交的参数中可以说明使用的编码方式,所以理论上能获得更大的兼容性。*/ Encoding
myEncoding= Encoding.GetEncoding("gb2312"); //确定用哪种中文编码方式 string param =
HttpUtility.UrlEncode("参数一", myEncoding) + "=" + HttpUtility.UrlEncode("值一",
myEncoding) +"&" + HttpUtility.UrlEncode("参数二", myEncoding) + "=" +
HttpUtility.UrlEncode("值二", myEncoding); byte[] paramBytes =
Encoding.ASCII.GetBytes(param);//参数转化为 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协议与服务器交互的情况,常用的是 GET 和 POST 方式。现在流行的 WebService 也是通过 HTTP
协议来交互的,使用的是 POST 方法。与以上稍有所不同的是, WebService 提交的数据内容和接收到的数据内容都是使用了 XML 方式编码。所以,
HttpWebRequest 也可以使用在调用 WebService 的场景下。
HttpWebRequest 请求通用方法 (不包含body数据)POST、GET请求 1 /// <summary> 2 ///
HTTP-GET方法,(不包含body数据)。 3 /// 发送 HTTP 请求并返回来自 Internet 资源的响应(HTML代码) 4 ///
</summary> 5 /// <param name="url">请求目标URL</param> 6 /// <returns>
HTTP-GET的响应结果</returns> 7 public HttpResult Get(string url) 8 { 9 return
Request(url, WebRequestMethods.Http.Get);10 } 1 /// <summary> 2 ///
HTTP-POST方法,(不包含body数据)。 3 /// 发送 HTTP 请求并返回来自 Internet 资源的响应(HTML代码) 4 ///
</summary> 5 /// <param name="url">请求目标URL</param> 6 /// <returns>
HTTP-POST的响应结果</returns> 7 public HttpResult Post(string url) 8 { 9 return
Request(url, WebRequestMethods.Http.Post);10 } (包含文本的body数据)请求
1 /// <summary> 2 /// HTTP请求(包含JSON文本的body数据) 3 /// </summary> 4 ///
<param name="url">请求目标URL</param> 5 /// <param name="data">
主体数据(JSON文本)。如果参数中有中文,请使用合适的编码方式进行编码,例如: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数据) 3 /// </summary> 4 /// <param name="url">请求目标URL</param>
5 /// <param name="data">主体数据(普通文本)。如果参数中有中文,请使用合适的编码方式进行编码,例如: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个方法调用了公用的业务方法,分别如下:
1 /// <summary> 2 /// HTTP请求,(不包含body数据)。 3 /// 发送 HTTP 请求并返回来自 Internet
资源的响应(HTML代码) 4 /// </summary> 5 /// <param name="url">请求目标URL</param> 6 ///
<param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param> 7 ///
<returns>HTTP的响应结果</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数据) 3 /// </summary> 4 /// <param name="url">
请求目标URL</param> 5 /// <param name="data">
主体数据(普通文本或者JSON文本)。如果参数中有中文,请使用合适的编码方式进行编码,例如: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);//将请求参数写入请求流中 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
响应成功,即状态码为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 /// 获取或设置请求的响应状态,success 或者
fail。建议使用常量:HttpResult.STATUS_SUCCESS 与 HttpResult.STATUS_FAIL 24 /// </summary>
25 public string Status { get; set; } 26 27 /// <summary> 28 ///
获取或设置请求的响应状态描述 29 /// </summary> 30 public string StatusDescription { get; set
; } 31 32 /// <summary> 33 /// 状态码。与 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 ///
附加信息(用户自定义内容,如Exception内容或者自定义提示信息)。 56 /// 当 Status 等于 success 时,该值为为空 57 ///
当 Status 等于 fail 时,该值为程序给出的用户自定义内容,如Exception内容或者自定义提示信息。 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 构造函数 74 /// <summary> 75 ///
初始化(所有成员默认值,需要后续赋值) 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">要复制其内容的来源</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 /// 转换为易读或便于打印的字符串格式 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
 
系列目录     【已更新最新开发文章,点击查看详细】
<https://www.cnblogs.com/SavionZhang/p/11422481.html>