using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Diagnostics;
using System.Threading;
public class WebUtils
{
/// <summary>
/// 生成Post请求字符串
/// </summary>
/// <param name="parameters"></param>
/// <returns></returns>
private static string BuildPostData(IDictionary<string, string> parameters)
{
StringBuilder builder = new StringBuilder();
bool flag = false;
IEnumerator<KeyValuePair<string, string>> enumerator = parameters.GetEnumerator();
while (enumerator.MoveNext())
{
KeyValuePair<string, string> current = enumerator.Current;
string key = current.Key;
string str2 = current.Value;
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(str2))
{
if (flag)
{
builder.Append("&");
}
builder.Append(key);
builder.Append("=");
builder.Append(Uri.EscapeDataString(str2));
flag = true;
}
}
return builder.ToString();
}
/// <summary>
/// 提交Get请求并获取输出内容
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string WebRequestGet(string url)
{
HttpWebRequest request = null;
try
{
request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.KeepAlive = true;
request.Timeout = 5000;
request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8";
HttpWebResponse rsp = (HttpWebResponse)request.GetResponse();
if (rsp.StatusCode != HttpStatusCode.OK) //如果服务器未响应,那么继续等待相应
{
return string.Empty;
}
Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet);
return GetResponseString(rsp, encoding);
}
catch (System.Net.WebException ex)
{
Thread.Sleep(5000);
//Log.Instance.AddErrorLog(url + "---" + ex.ToString());
}
catch (Exception ex)
{
//Log.Instance.AddErrorLog(url + "---" + ex);
}
finally
{
request.Abort();
}
return string.Empty;
}
public static string GetRedirectUrl(string url)
{
HttpWebRequest request = null;
HttpWebResponse rsp = null;
try
{
request = (HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = true;
request.MaximumAutomaticRedirections = 1;
request.Method = "GET";
request.KeepAlive = true;
request.Timeout = 5000;
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8";
request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
rsp = (HttpWebResponse)request.GetResponse();
if (rsp.StatusCode != HttpStatusCode.OK) //如果服务器未响应,那么继续等待相应
{
return string.Empty;
}
string str = rsp.ResponseUri.Host;
return str;
}
catch (System.Net.WebException ex)
{
Thread.Sleep(5000);
//Log.Instance.AddErrorLog(url+ "---"+ex.ToString());
}
catch (Exception ex)
{
//Log.Instance.AddErrorLog(url + "---" + ex);
}
finally
{
if (request != null) request.Abort();
if (rsp != null) rsp.Close();
}
return string.Empty;
}
//获取指定页面的源代码
/// <summary>
/// 提交Post请求并获取输出内容
/// </summary>
/// <param name="url">URL地址</param>
/// <param name="parameters">提交参数</param>
/// <returns></returns>
public static string WebRequestPost(string url, IDictionary<string, string> parameters)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.KeepAlive = true;
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8";
request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
byte[] bytes = Encoding.UTF8.GetBytes(BuildPostData(parameters));
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
var rsp = (HttpWebResponse)request.GetResponse();
if (rsp.StatusCode != HttpStatusCode.OK) //如果服务器未响应,那么继续等待相应
{
return string.Empty;
}
Encoding encoding;
try
{
encoding = Encoding.GetEncoding(rsp.CharacterSet);
}
catch
{
encoding = Encoding.GetEncoding("UTF-8");
}
return GetResponseString(rsp, encoding);
}
/// <summary>
/// 获取输出字符串内容
/// </summary>
/// <param name="rsp"></param>
/// <param name="encoding"></param>
/// <returns></returns>
private static string GetResponseString(HttpWebResponse rsp, Encoding encoding)
{
var builder = new StringBuilder();
Stream responseStream = null;
StreamReader reader = null;
try
{
responseStream = rsp.GetResponseStream();
reader = new StreamReader(responseStream, encoding);
char[] buffer = new char[0x100];
int charCount = 0;
while ((charCount = reader.Read(buffer, 0, buffer.Length)) > 0)
{
builder.Append(buffer, 0, charCount);
}
}
finally
{
if (reader != null)
{
reader.Close();
}
if (responseStream != null)
{
responseStream.Close();
}
if (rsp != null)
{
rsp.Close();
}
}
return builder.ToString();
}
}
http://www.cnblogs.com/Thriving-Country/archive/2011/09/18/2180143.html
http://www.cnblogs.com/1971ruru/archive/2012/04/11/2442589.html
随着REST风格的流行,直接通过 HttpWebRequest 进行服务调用的客户端应用越来越多。这里总结一些可能需要费时调查的经验,希望能帮助大家。
1. 用完的HttpWebRequest要Abort()或者要把 Response.Close()
否则会导致请求Timeout。 (HttpWebRequest.Method默认是GET)
- static void Main( string [] args)
- {
- for ( int i = 0; i < 10; i++)
- {
- Console.Write( "[{0}] Request - ", i + 1);
- TryGet( "https://login.live.com/" );
- }
- Console.Read();
- }
- static void TryGet( object obj)
- {
- try
- {
- HttpWebRequest webReq = null ;
- string url = ( string )obj;
- webReq = (HttpWebRequest)HttpWebRequest.Create(url);
- webReq.Timeout = 20 * 1000;
- var resp = webReq.GetResponse() as HttpWebResponse;
- resp.Close();
- Console.WriteLine( "Get Response StatusCode: {0}({1})",
- resp.StatusCode, ( int)resp.StatusCode);
- }
- catch (WebException we)
- {
- Console.WriteLine( "Get Response StatusCode: {0}({1})",
- we.Status, ( int )we.Status);
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex);
- }
- }
上面的代码,会从第3次Request开始出现Timeout,因为GetResponse 后 Stream打开未关闭。
解决方法:上面的代码中加上 resp.Close(); 或者 webReq.Abort(); 就能解决。
2. 多线程中调用 HttpWebRequest 时,需要设置 ServicePointManager.DefaultConnectionLimit 数(默认连接数是 2)。
当多线程请求时,同时的连接数超过Limit时,GetResponse会抛出 Timeout WebException。
- // 用多线程同时发出4个请求
- WaitCallback methodTarget = new WaitCallback(TryGet);
- ThreadPool.QueueUserWorkItem(methodTarget, "https://login.live.com/" );
- ThreadPool.QueueUserWorkItem(methodTarget, "https://login.live.com/");
- ThreadPool.QueueUserWorkItem(methodTarget, "https://login.live.com/" );
- ThreadPool.QueueUserWorkItem(methodTarget, "https://login.live.com/");
解决方法:在GetResponse()之前设置 ServicePointManager.DefaultConnectionLimit = 100;
3. 当请求一个基于SSL的服务时,默认的验证行为都在 ServicePointManager 定义:
ServicePointManager.CheckCertificateRevocationList = true;
如果请求的服务端证书没有第三方的认证支持,则请求会失败,如果要完全信任服务端证书,则可以将
CheckCertificateRevocationList 设为 false。
4. 可以在 <system.net> 配置节中配置 HttpWebRequest 的属性,包括 WebProxy
- <system.net>
- <connectionManagement>
- </connectionManagement>
- <defaultProxy>
- <proxy proxyaddress= "http://xxx.xxx.xxx.xxx:xxx" bypassonlocal= "False" />
- </defaultProxy>
- <settings>
- <httpWebRequest useUnsafeHeaderParsing= "true"/>
- <servicePointManager checkCertificateName= "true"
- checkCertificateRevocationList= "true"
- enableDnsRoundRobin= "true"
- expect100Continue= "true"
- useNagleAlgorithm= "true" />
- </settings>
- </system.net>