文章目录
前言
关于网络数据请求的类很多,httpwebrequest,webrequest,webclient以及httpclient,具体差别在此不在赘述,在应用方面介绍webclient与httpclient则显得比较比较简单粗暴,httpwebrequest继承自webrequest,可通过参数进行请求控制。
1. 基于WebClient的post/get数据请求:
1.1 get
using (var client = new WebClient())
{
client.Encoding = Encoding.GetEncoding("utf-8");
var responseString = client.DownloadString("http://www.sojson.com/open/api/weather/json.shtml?city=闵行区");
Console.WriteLine(responseString);
Console.ReadKey();
}
1.2 post
using (var client = new WebClient())
{
client.Encoding = Encoding.GetEncoding("utf-8");
var values = new NameValueCollection();
values["api_key"] = "**********";
values["api_secret"] = "**********";
values["image_url"] = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1508759666809&di=b3748df04c5e54d18fe52ee413f72f37&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F562c11dfa9ec8a1389c45414fd03918fa1ecc06c.jpg";
var response = client.UploadValues("https://api-cn.faceplusplus.com/facepp/v3/detect", values);
var responseString = Encoding.Default.GetString(response);
Console.WriteLine(responseString);
Console.ReadKey();
}
2. 基于HttpWebRequest 的get/post方法
2.1 get
/// <summary>
/// get
/// </summary>
/// <param name="url">url="http:**********"+"?"+"key1=***&key2=***"</param>
/// example :http://www.sojson.com/open/api/weather/json.shtml?city=闵行区
/// <returns></returns>
public static string GetHttp(string url)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "GET";
httpWebRequest.Timeout = 20000;
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
string responseContent = streamReader.ReadToEnd();
httpWebResponse.Close();
streamReader.Close();
return responseContent;
}
2.2 post
post提交数据的方式有四种,具体体现在contentType有四种方式:application/x-www-form-urlencoded,multipart/form-data,application/json以及text/xml,本文主讲前两种方法,第三种即为通过json格式发送数据,第四种通过xml格式发送。
2.2.1 contentType=application/x-www-form-urlencoded
此种方式应用比较普遍,但是当传递参数中存在文件如图片时则需要用到multipart/form-data方式
/// <summary>
/// 采用httpwebrequest post方法请求数据
/// </summary>
/// <param name="url"></param>
/// <param name="body">body是要传递的参数,格式:api_keyi=xxxxxx&api_secret=xxxxxxx</param>
/// <param name="contentType">application/x-www-form-urlencoded</param>
/// <returns></returns>
public static string PostHttpWebRequest(string url, string body, string contentType)
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = contentType;
httpWebRequest.Method = "POST";
httpWebRequest.Timeout = 1000;
byte[] btBodys = Encoding.UTF8.GetBytes(body);
httpWebRequest.ContentLength = btBodys.Length;
httpWebRequest.GetRequestStream().Write(btBodys, 0, btBodys.Length);
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
string responseContent = streamReader.ReadToEnd();
httpWebResponse.Close();
streamReader.Close();
httpWebRequest.Abort();
httpWebResponse.Close();
return responseContent;
}
2.2.2 contentType=multipart/form-data
此种方式请求数据时,请求的数据流比较繁琐,需要自己来确定,即httpWebRequest.GetRequestStream().Write(btBodys, 0, btBodys.Length);中的btBodys需要自己构造,比较繁琐。其构造主体如下所示:
class RequestForm
{
public class PostImage //image
{
public string fullPath;
public string imageName;
public string contentType= "application/octet-stream";
public PostImage(string path)
{
fullPath = path;
imageName = Path.GetFileName(path);
}
}
class PostFile //files
{
}
private static readonly Encoding encoding = Encoding.UTF8;
/// <summary>
/// 调用入口
/// </summary>
/// <param name="postParameter"></param>
/// <param name="url"></param>
/// <returns></returns>
public static string OnRequest(Dictionary<string,object> postParameter,string url)//主调用程序
{
string boundary = string.Format("{0}", Guid.NewGuid());
byte[] body=GetPostForm(postParameter, boundary);
string contentType = "multipart/form-data; boundary=" + boundary;
return OnWebRequest(body, url, contentType);
//return PostForm(url, contentType, body);
}
private static byte[] GetPostForm(Dictionary<string, object> postParameter,string boundary)//获取请求主体
{
Stream stream = new MemoryStream();
bool isFirstPara = false;
foreach (KeyValuePair<string, object> para in postParameter)
{
if (isFirstPara)
{
stream.Write(encoding.GetBytes("\r\n"), 0,encoding.GetByteCount("\r\n"));
}
isFirstPara = true;
//若需要添加文件信息如txt等增加else分支添加
if (para.Value is PostImage)
{
PostImage postImage = (PostImage)para.Value;
string imageStatement = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n", new object[]
{
boundary,
para.Key,
postImage.imageName??para.Key,
postImage.contentType??"application/octet-stream"
});
stream.Write(encoding.GetBytes(imageStatement), 0, encoding.GetByteCount(imageStatement));
byte[] imageContent = GetImageInfo(postImage.fullPath);
stream.Write(imageContent, 0, imageContent.Length);
}
else
{
string regularStatement = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}", boundary, para.Key, para.Value);
stream.Write(encoding.GetBytes(regularStatement), 0, encoding.GetByteCount(regularStatement));
}
}
string end = "\r\n--" + boundary + "--\r\n";
stream.Write(encoding.GetBytes(end), 0, encoding.GetByteCount(end));
stream.Position = 0L;
byte[] bodyArr = new byte[stream.Length];
stream.Read(bodyArr, 0, bodyArr.Length);
stream.Close();
return bodyArr;
}
private static string OnWebRequest(byte[] postForm,string url,string contentType)//数据请求
{
HttpWebRequest request =(HttpWebRequest)WebRequest.Create(url);
//try
//{
// HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
//}
//catch(WebException ex)
//{
// return ex.Message;
//}
if (request == null) return "Failed to connect url";
request.Method = "POST";
request.Timeout =2000;
request.ReadWriteTimeout =2000;
request.ContentType = contentType;
request.ContentLength = (long)postForm.Length;
try
{
using (Stream requestStream = request.GetRequestStream())
{
int bufferSize = 4096;
int position = 0;
while (position < postForm.Length)
{
bufferSize = Math.Min(bufferSize, postForm.Length - position);
byte[] data = new byte[bufferSize];
Array.Copy(postForm, position, data, 0, bufferSize);
requestStream.Write(data, 0, data.Length);
position += data.Length;
}
//requestStream.Write(formData, 0, formData.Length);
requestStream.Close();
}
}
catch (Exception ex)
{
return ex.Message;
}
HttpWebResponse result;
try
{
result = (HttpWebResponse)(request.GetResponse());
}
catch (Exception ex)
{
return ex.Message;
}
StreamReader streamReader = new StreamReader(result.GetResponseStream());
return streamReader.ReadToEnd();
}
private static byte[] GetImageInfo(string path)//通过路径获取图片信息
{
Bitmap bmp = new Bitmap(path);
byte[] imageInfo;
using (Stream stream = new MemoryStream())
{
bmp.Save(stream,ImageFormat.Jpeg);
byte[] arr = new byte[stream.Length];
stream.Position = 0;
stream.Read(arr, 0, (int)stream.Length);
stream.Close();
imageInfo = arr;
}
return imageInfo;
}
}
2.2.3 调用代码
static void Main(string[] args)
{
string imagePath = @"D:\test\image\1.jpg";
string url = "https://api-cn.faceplusplus.com/facepp/v3/detect";
RequestForm.PostImage postImage = new RequestForm.PostImage(imagePath);
Dictionary<string, object> postParameter = new Dictionary<string, object>();
postParameter.Add("api_key", "*************************");
postParameter.Add("api_secret", "**************************");
postParameter.Add("image_file", postImage);
//postParameter.Add("image_url", "http://imgtu.5011.net/uploads/content/20170328/7150651490664042.jpg");
string result = RequestForm.OnRequest(postParameter, url);
Console.WriteLine(result);
Console.ReadKey();
}
调用时参数为请求的url以及Dictionary<string, object> 类型的主体参数,传入图片时只需要一个参数调用时的key(上述代码为"image_file")和包含图片路径的对象postImage,如果传入参数还需要其他文件如Txt格式等的文件时,只需要通过filestream读取出来即可