一个 http 请求类 ,支持文件上传,从淘宝 top sdk 里面扣出来的,蛮好用的,做个记录而已。

调用代码:

       Dictionary<string, string> textParas = new Dictionary<string, string>();
textParas.Add("username", "jersey");
textParas.Add("password", "000000"); Dictionary<string, FileItem> fileParas = new Dictionary<string, FileItem>();
fileParas.Add("file1", new FileItem("E:\\123.jpg"));
fileParas.Add("file2", new FileItem("E:\\123.jpg")); WebUtils webUtils=new WebUtils();
webUtils.Timeout=50000;
webUtils.DoPost("http://www.baidu.com/api/index.php",textParas,fileParas,null);

  

类代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web; namespace tools
{
/// <summary>
/// 网络工具类。
/// </summary>
public sealed class WebUtils
{
private int _timeout = 20000;
private int _readWriteTimeout = 60000;
private bool _ignoreSSLCheck = true;
private bool _disableWebProxy = false; /// <summary>
/// 等待请求开始返回的超时时间
/// </summary>
public int Timeout
{
get { return this._timeout; }
set { this._timeout = value; }
} /// <summary>
/// 等待读取数据完成的超时时间
/// </summary>
public int ReadWriteTimeout
{
get { return this._readWriteTimeout; }
set { this._readWriteTimeout = value; }
} /// <summary>
/// 是否忽略SSL检查
/// </summary>
public bool IgnoreSSLCheck
{
get { return this._ignoreSSLCheck; }
set { this._ignoreSSLCheck = value; }
} /// <summary>
/// 是否禁用本地代理
/// </summary>
public bool DisableWebProxy
{
get { return this._disableWebProxy; }
set { this._disableWebProxy = value; }
} /// <summary>
/// 执行HTTP POST请求。
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="textParams">请求文本参数</param>
/// <returns>HTTP响应</returns>
public string DoPost(string url, IDictionary<string, string> textParams)
{
return DoPost(url, textParams, null);
} /// <summary>
/// 执行HTTP POST请求。
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="textParams">请求文本参数</param>
/// <param name="headerParams">请求头部参数</param>
/// <returns>HTTP响应</returns>
public string DoPost(string url, IDictionary<string, string> textParams, IDictionary<string, string> headerParams)
{
HttpWebRequest req = GetWebRequest(url, "POST", headerParams);
req.ContentType = "application/x-www-form-urlencoded;charset=utf-8"; byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(textParams));
System.IO.Stream reqStream = req.GetRequestStream();
reqStream.Write(postData, 0, postData.Length);
reqStream.Close(); HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
Encoding encoding = GetResponseEncoding(rsp);
return GetResponseAsString(rsp, encoding);
} /// <summary>
/// 执行HTTP GET请求。
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="textParams">请求文本参数</param>
/// <returns>HTTP响应</returns>
public string DoGet(string url, IDictionary<string, string> textParams)
{
return DoGet(url, textParams, null);
} /// <summary>
/// 执行HTTP GET请求。
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="textParams">请求文本参数</param>
/// <param name="headerParams">请求头部参数</param>
/// <returns>HTTP响应</returns>
public string DoGet(string url, IDictionary<string, string> textParams, IDictionary<string, string> headerParams)
{
if (textParams != null && textParams.Count > 0)
{
url = BuildRequestUrl(url, textParams);
} HttpWebRequest req = GetWebRequest(url, "GET", headerParams);
req.ContentType = "application/x-www-form-urlencoded;charset=utf-8"; HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
Encoding encoding = GetResponseEncoding(rsp);
return GetResponseAsString(rsp, encoding);
} /// <summary>
/// 执行带文件上传的HTTP POST请求。
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="textParams">请求文本参数</param>
/// <param name="fileParams">请求文件参数</param>
/// <param name="headerParams">请求头部参数</param>
/// <returns>HTTP响应</returns>
public string DoPost(string url, IDictionary<string, string> textParams, IDictionary<string, FileItem> fileParams, IDictionary<string, string> headerParams)
{
// 如果没有文件参数,则走普通POST请求
if (fileParams == null || fileParams.Count == 0)
{
return DoPost(url, textParams, headerParams);
} string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线 HttpWebRequest req = GetWebRequest(url, "POST", headerParams);
req.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary; System.IO.Stream reqStream = req.GetRequestStream();
byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); // 组装文本请求参数
string textTemplate = "Content-Disposition:form-data;name=\"{0}\"\r\nContent-Type:text/plain\r\n\r\n{1}";
foreach (KeyValuePair<string, string> kv in textParams)
{
string textEntry = string.Format(textTemplate, kv.Key, kv.Value);
byte[] itemBytes = Encoding.UTF8.GetBytes(textEntry);
reqStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
reqStream.Write(itemBytes, 0, itemBytes.Length);
} // 组装文件请求参数
string fileTemplate = "Content-Disposition:form-data;name=\"{0}\";filename=\"{1}\"\r\nContent-Type:{2}\r\n\r\n";
foreach (KeyValuePair<string, FileItem> kv in fileParams)
{
string key = kv.Key;
FileItem fileItem = kv.Value;
if (!fileItem.IsValid())
{
throw new ArgumentException("FileItem is invalid");
}
string fileEntry = string.Format(fileTemplate, key, fileItem.GetFileName(), fileItem.GetMimeType());
byte[] itemBytes = Encoding.UTF8.GetBytes(fileEntry);
reqStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
reqStream.Write(itemBytes, 0, itemBytes.Length);
fileItem.Write(reqStream);
} reqStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
reqStream.Close(); HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
Encoding encoding = GetResponseEncoding(rsp);
return GetResponseAsString(rsp, encoding);
} /// <summary>
/// 执行带body体的POST请求。
/// </summary>
/// <param name="url">请求地址,含URL参数</param>
/// <param name="body">请求body体字节流</param>
/// <param name="contentType">body内容类型</param>
/// <param name="headerParams">请求头部参数</param>
/// <returns>HTTP响应</returns>
public string DoPost(string url, byte[] body, string contentType, IDictionary<string, string> headerParams)
{
HttpWebRequest req = GetWebRequest(url, "POST", headerParams);
req.ContentType = contentType;
if (body != null)
{
System.IO.Stream reqStream = req.GetRequestStream();
reqStream.Write(body, 0, body.Length);
reqStream.Close();
}
HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
Encoding encoding = GetResponseEncoding(rsp);
return GetResponseAsString(rsp, encoding);
} public HttpWebRequest GetWebRequest(string url, string method, IDictionary<string, string> headerParams)
{
HttpWebRequest req = null;
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
if (this._ignoreSSLCheck)
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(TrustAllValidationCallback);
}
req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
}
else
{
req = (HttpWebRequest)WebRequest.Create(url);
} if (this._disableWebProxy)
{
req.Proxy = null;
} if (headerParams != null && headerParams.Count > 0)
{
foreach (string key in headerParams.Keys)
{
req.Headers.Add(key, headerParams[key]);
}
} req.ServicePoint.Expect100Continue = false;
req.Method = method;
req.KeepAlive = true;
req.UserAgent = "top-sdk-net";
req.Accept = "text/xml,text/javascript";
req.Timeout = this._timeout;
req.ReadWriteTimeout = this._readWriteTimeout; return req;
} /// <summary>
/// 把响应流转换为文本。
/// </summary>
/// <param name="rsp">响应流对象</param>
/// <param name="encoding">编码方式</param>
/// <returns>响应文本</returns>
public string GetResponseAsString(HttpWebResponse rsp, Encoding encoding)
{
Stream stream = null;
StreamReader reader = null; try
{
// 以字符流的方式读取HTTP响应
stream = rsp.GetResponseStream();
if (Constants.CONTENT_ENCODING_GZIP.Equals(rsp.ContentEncoding, StringComparison.OrdinalIgnoreCase))
{
stream = new GZipStream(stream, CompressionMode.Decompress);
}
reader = new StreamReader(stream, encoding);
return reader.ReadToEnd();
}
finally
{
// 释放资源
if (reader != null) reader.Close();
if (stream != null) stream.Close();
if (rsp != null) rsp.Close();
}
} /// <summary>
/// 组装含参数的请求URL。
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="parameters">请求参数映射</param>
/// <returns>带参数的请求URL</returns>
public static string BuildRequestUrl(string url, IDictionary<string, string> parameters)
{
if (parameters != null && parameters.Count > 0)
{
return BuildRequestUrl(url, BuildQuery(parameters));
}
return url;
} /// <summary>
/// 组装含参数的请求URL。
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="queries">一个或多个经过URL编码后的请求参数串</param>
/// <returns>带参数的请求URL</returns>
public static string BuildRequestUrl(string url, params string[] queries)
{
if (queries == null || queries.Length == 0)
{
return url;
} StringBuilder newUrl = new StringBuilder(url);
bool hasQuery = url.Contains("?");
bool hasPrepend = url.EndsWith("?") || url.EndsWith("&"); foreach (string query in queries)
{
if (!string.IsNullOrEmpty(query))
{
if (!hasPrepend)
{
if (hasQuery)
{
newUrl.Append("&");
}
else
{
newUrl.Append("?");
hasQuery = true;
}
}
newUrl.Append(query);
hasPrepend = false;
}
}
return newUrl.ToString();
} /// <summary>
/// 组装普通文本请求参数。
/// </summary>
/// <param name="parameters">Key-Value形式请求参数字典</param>
/// <returns>URL编码后的请求数据</returns>
public static string BuildQuery(IDictionary<string, string> parameters)
{
if (parameters == null || parameters.Count == 0)
{
return null;
} StringBuilder query = new StringBuilder();
bool hasParam = false; foreach (KeyValuePair<string, string> kv in parameters)
{
string name = kv.Key;
string value = kv.Value;
// 忽略参数名或参数值为空的参数
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
{
if (hasParam)
{
query.Append("&");
} query.Append(name);
query.Append("=");
query.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
hasParam = true;
}
} return query.ToString();
} private Encoding GetResponseEncoding(HttpWebResponse rsp)
{
string charset = rsp.CharacterSet;
if (string.IsNullOrEmpty(charset))
{
charset = Constants.CHARSET_UTF8;
}
return Encoding.GetEncoding(charset);
} private static bool TrustAllValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true; // 忽略SSL证书检查
}
} public class Constants
{
public const string CONTENT_ENCODING_GZIP = "gzip";
public const string CHARSET_UTF8 = "utf-8";
public const string CTYPE_DEFAULT = "application/octet-stream";
public const int READ_BUFFER_SIZE = 1024 * 4;
} /// <summary>
/// 文件元数据。
/// 可以使用以下几种构造方法:
/// 本地路径:new FileItem("C:/temp.jpg");
/// 本地文件:new FileItem(new FileInfo("C:/temp.jpg"));
/// 字节数组:new FileItem("abc.jpg", bytes);
/// 输入流:new FileItem("abc.jpg", stream);
/// </summary>
public class FileItem
{
private Contract contract; /// <summary>
/// 基于本地文件的构造器。
/// </summary>
/// <param name="fileInfo">本地文件</param>
public FileItem(FileInfo fileInfo)
{
this.contract = new LocalContract(fileInfo);
} /// <summary>
/// 基于本地文件全路径的构造器。
/// </summary>
/// <param name="filePath">本地文件全路径</param>
public FileItem(string filePath)
: this(new FileInfo(filePath))
{
} /// <summary>
/// 基于文件名和字节数组的构造器。
/// </summary>
/// <param name="fileName">文件名称(服务端持久化字节数组到磁盘时的文件名)</param>
/// <param name="content">文件字节数组</param>
public FileItem(string fileName, byte[] content)
: this(fileName, content, null)
{
} /// <summary>
/// 基于文件名、字节数组和媒体类型的构造器。
/// </summary>
/// <param name="fileName">文件名(服务端持久化字节数组到磁盘时的文件名)</param>
/// <param name="content">文件字字节数组</param>
/// <param name="mimeType">媒体类型</param>
public FileItem(string fileName, byte[] content, string mimeType)
{
this.contract = new ByteArrayContract(fileName, content, mimeType);
} /// <summary>
/// 基于文件名和输入流的构造器。
/// </summary>
/// <param name="fileName">文件名称(服务端持久化输入流到磁盘时的文件名)</param>
/// <param name="content">文件输入流</param>
public FileItem(string fileName, Stream stream)
: this(fileName, stream, null)
{
} /// <summary>
/// 基于文件名、输入流和媒体类型的构造器。
/// </summary>
/// <param name="fileName">文件名(服务端持久化输入流到磁盘时的文件名)</param>
/// <param name="content">文件输入流</param>
/// <param name="mimeType">媒体类型</param>
public FileItem(string fileName, Stream stream, string mimeType)
{
this.contract = new StreamContract(fileName, stream, mimeType);
} public bool IsValid()
{
return this.contract.IsValid();
} public long GetFileLength()
{
return this.contract.GetFileLength();
} public string GetFileName()
{
return this.contract.GetFileName();
} public string GetMimeType()
{
return this.contract.GetMimeType();
} public void Write(Stream output)
{
this.contract.Write(output);
}
} internal interface Contract
{
bool IsValid();
string GetFileName();
string GetMimeType();
long GetFileLength();
void Write(Stream output);
} internal class LocalContract : Contract
{
private FileInfo fileInfo; public LocalContract(FileInfo fileInfo)
{
this.fileInfo = fileInfo;
} public long GetFileLength()
{
return this.fileInfo.Length;
} public string GetFileName()
{
return this.fileInfo.Name;
} public string GetMimeType()
{
return Constants.CTYPE_DEFAULT;
} public bool IsValid()
{
return this.fileInfo != null && this.fileInfo.Exists;
} public void Write(Stream output)
{
using (BufferedStream bfs = new BufferedStream(this.fileInfo.OpenRead()))
{
int n = 0;
byte[] buffer = new byte[Constants.READ_BUFFER_SIZE];
while ((n = bfs.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, n);
}
}
}
} internal class ByteArrayContract : Contract
{
private string fileName;
private byte[] content;
private string mimeType; public ByteArrayContract(string fileName, byte[] content, string mimeType)
{
this.fileName = fileName;
this.content = content;
this.mimeType = mimeType;
} public bool IsValid()
{
return this.content != null && this.fileName != null;
} public long GetFileLength()
{
return this.content.Length;
} public string GetFileName()
{
return this.fileName;
} public string GetMimeType()
{
if (string.IsNullOrEmpty(this.mimeType))
{
return Constants.CTYPE_DEFAULT;
}
else
{
return this.mimeType;
}
} public void Write(Stream output)
{
output.Write(this.content, 0, this.content.Length);
}
} internal class StreamContract : Contract
{
private string fileName;
private Stream stream;
private string mimeType; public StreamContract(string fileName, Stream stream, string mimeType)
{
this.fileName = fileName;
this.stream = stream;
this.mimeType = mimeType;
} public long GetFileLength()
{
return 0L;
} public string GetFileName()
{
return this.fileName;
} public string GetMimeType()
{
if (string.IsNullOrEmpty(mimeType))
{
return Constants.CTYPE_DEFAULT;
}
else
{
return this.mimeType;
}
} public bool IsValid()
{
return this.stream != null && this.fileName != null;
} public void Write(Stream output)
{
using (this.stream)
{
int n = 0;
byte[] buffer = new byte[Constants.READ_BUFFER_SIZE];
while ((n = this.stream.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, n);
}
}
}
}
}

  

一个比较强大的HTTP请求类,支持文本参数和文件参数。的更多相关文章

  1. C# 一个特别不错的http请求类

    using System; using System.Collections; using System.Collections.Generic; using System.Collections.S ...

  2. Afreechart很强大的图表库,支持股票曲线图,饼图,曲线

    Afreechart是一个很强大的图表库,支持股票曲线图,饼图,曲线等.源码下载:http://www.23code.com/afreechart/

  3. 一个linux下简单的纯C++实现Http请求类(GET,POST,上传,下载)

    目录 一个linux下简单的纯C++实现Http请求类(GET,POST,上传,下载) Http协议简述 HttpRequest类设计 请求部分 接收部分 关于上传和下载 Cpp实现 关于源码中的Lo ...

  4. 基于Volley,Gson封装支持JWT无状态安全验证和数据防篡改的GsonRequest网络请求类

    这段时间做新的Android项目的client和和REST API通讯框架架构设计.使用了非常多新技术,终于的方案也相当简洁优雅.client仅仅须要传Java对象,server端返回json字符串, ...

  5. 一个高性能的对象属性复制类,支持不同类型对象间复制,支持Nullable<T>类型属性

    由于在实际应用中,需要对大量的对象属性进行复制,原来的方法是通过反射实现,在量大了以后,反射的性能问题就凸显出来了,必须用Emit来实现. 搜了一圈代码,没发现适合的,要么只能在相同类型对象间复制,要 ...

  6. block传值以及利用block封装一个网络请求类

    1.block在俩个UIViewController间传值 近期刚学了几招block 的高级使用方法,事实上就是利用block语法在俩个UIViewController之间传值,在这里分享给刚開始学习 ...

  7. HttpUtil工具类,发送Get/Post请求,支持Http和Https协议

    HttpUtil工具类,发送Get/Post请求,支持Http和Https协议 使用用Httpclient封装的HttpUtil工具类,发送Get/Post请求 1. maven引入httpclien ...

  8. AndroidInject项目使用动态代理增加对网络请求的支持

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3540427.html AndroidInject项目是我写的一 ...

  9. Servlet(五):一个Servlet处理多个请求

    一.为什么要使用一个Servlet来处理多个请求? 当浏览器发送了一次请求到服务器时,servlet容器会根据请求的url-pattern找到对应的Servlet类,执行对应的doPost或doGet ...

随机推荐

  1. 统计学中z分布、t分布、F分布及χ^2分布

    Z就是正态分布,X^2分布是一个正态分布的平方,t分布是一个正态分布除以(一个X^2分布除以它的自由度然后开根号),F分布是两个卡方分布分布除以他们各自的自由度再相除 比如X是一个Z分布,Y(n)=X ...

  2. IntelliJ IDEA 2017版 快捷键CTRL + SHIFT + A无效如何调试(详细的开启idea自动make功能 )

    1.前景描述 因为我把编译器的快捷键都设置成eclipse模式了,所以要做热部署的时候,需要CTRL + SHIFT + A --> 查找Registry --> 找到并勾选compile ...

  3. tp5和gateworer集成

    第一步:安装thinkpph程序包 第二步:切换到根目录,使用composer require workerman/gateway-worker 安装Linux版本的gateway.(前提是你服务器安 ...

  4. mysql 更新替换字符串

    update zxg set newlevel = REPLACE(newlevel,'b','') 把表zxg中的newlevel字段中的b删除

  5. Appium之启用手机桌面APP的多种方法

    方法一: 其实之前的随笔 Appium之连续启动多个应用(APP)中已经介绍了可以用appium下的start_activity()方法来启动一个应用,那这里就不再说明啦. 方法二: 因为有时用sta ...

  6. 23 DesignPatterns学习笔记:C++语言实现 --- 2.5 Factory

    23 DesignPatterns学习笔记:C++语言实现 --- 2.5 Factory 2016-07-18 (www.cnblogs.com/icmzn) 模式理解   1. Flyweight ...

  7. 点滴笔记(二):利用JS对象把值传到后台

    记得以前刚写asp.net 从前台往后台传值 都是var data=A,B,C,D,E; 循环添加用逗号隔开 后台还要被测试测出只输入,就错了 哈哈..后来用✈◆类似的符号隔开 不是长久之计... 现 ...

  8. java中的软引用,弱引用,虚引用

    http://zh.wikipedia.org/wiki/%E5%BC%B1%E5%BC%95%E7%94%A8 有些语言包含多种强度的弱引用.例如Java,在java.lang.ref[1]包中定义 ...

  9. tinymce与prism代码高亮实现及汉化的配置

    简单介绍:TinyMCE是一个轻量级的基于浏览器的所见即所得编辑器,由JavaScript写成.它对IE6+和Firefox1.5+都有着非常良好的支持.功能方强大,并且功能配置灵活简单.另一特点是加 ...

  10. java invoke(转摘)

      JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的以及动态调用对象的方法的功能称为java语言的反射机制 ...