关于网络数据请求的类很多,httpwebrequest,webrequest,webclient以及httpclient,具体差别在此不在赘述,在应用方面介绍webclient与httpclient则显得比较比较简单粗暴,httpwebrequest继承自webrequest,可通过参数进行请求控制。

1)基于WebClient的post/get数据请求:

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();
}

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方法

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 = ; HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
string responseContent = streamReader.ReadToEnd(); httpWebResponse.Close();
streamReader.Close(); return responseContent;
}

post

post提交数据的方式有四种,具体体现在contentType有四种方式:application/x-www-form-urlencoded,multipart/form-data,application/json以及text/xml,本文主讲前两种方法,第三种即为通过json格式发送数据,第四种通过xml格式发送。

(一)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 = ; byte[] btBodys = Encoding.UTF8.GetBytes(body);
httpWebRequest.ContentLength = btBodys.Length;
httpWebRequest.GetRequestStream().Write(btBodys, , 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;
}

(二)contentType=multipart/form-data

此种方式请求数据时,请求的数据流比较繁琐,需要自己来确定,即httpWebRequest.GetRequestStream().Write(btBodys, 0, btBodys.Length);中的btBodys需要自己构造,比较繁琐。其构造主体如下所示:

HTTP请求头:
....
multipart/form-data; charset=utf-8;boundary=AaB03x //boundary=AaB03x为下文请求体中用于分隔不同请求参数的文本边界请求头可以放在请求数据流中,也可以直接在contentType中定义即contentType=multipart/form-data; charset=utf-8;boundary=AaB03x
....

HTTP请求体:
--AaB03x                                                                  //第一个参数边界:即在请求头中boundary文本AaB03x前加‘’--‘’
Content-Disposition: form-data; name="key1"         //换行,在此加入数据的第一个参数名称
                                                                                //继续换行(即空一行)
value1                                                                     //添加第一个参数对应的值
--AaB03x                                                                 //第二个参数边界:即在请求头中boundary文本AaB03x前加‘’--‘’,字符串参数格式均与上同
Content-disposition: form-data; name="key2"

value2
--AaB03x                                                                  //边界,此处添加图片
Content-disposition: form-data; name="key3"; filename="file"    // filename表示文件名,其值与是否为真实文件名无关
Content-Type: application/octet-stream                   // 表示文件形式,这也是与字符串参数的不同

图片数据                                                                  // 图片数据,为二进制byte类型数据
--AaB03x--                                                               //结束边界,为boundary文本值AaB03x前后各加加‘’--‘’

PS:

1)边界boundary的值未不会重复的字符串,大小等因素基本没影响,一般采用boundary = string.Format("{0}", Guid.NewGuid());生成,或者采用时间参数如boundary =DateTime.Now.Ticks.ToString();

代码如下

    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"), ,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), , encoding.GetByteCount(imageStatement));
byte[] imageContent = GetImageInfo(postImage.fullPath);
stream.Write(imageContent, , 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), , encoding.GetByteCount(regularStatement));
}
} string end = "\r\n--" + boundary + "--\r\n";
stream.Write(encoding.GetBytes(end), , encoding.GetByteCount(end));
stream.Position = 0L;
byte[] bodyArr = new byte[stream.Length];
stream.Read(bodyArr, , 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 =;
request.ReadWriteTimeout =;
request.ContentType = contentType;
request.ContentLength = (long)postForm.Length; try
{
using (Stream requestStream = request.GetRequestStream())
{
int bufferSize = ;
int position = ;
while (position < postForm.Length)
{
bufferSize = Math.Min(bufferSize, postForm.Length - position); byte[] data = new byte[bufferSize];
Array.Copy(postForm, position, data, , bufferSize);
requestStream.Write(data, , 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 = ;
stream.Read(arr, , (int)stream.Length);
stream.Close();
imageInfo = arr;
} return imageInfo;
} }

调用代码:

        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读取出来即可

网络数据请求request的更多相关文章

  1. iOS - NetRequest 网络数据请求

    1.网络请求 1.1 网络通讯三要素 1.IP 地址(主机名): 网络中设备的唯一标示.不易记忆,可以用主机名(域名). 1) IP V4: 0~255.0~255.0~255.0~255 ,共有 2 ...

  2. swift网络数据请求方法

    搭建一个apache服务器,用php编写一个返回给客户端请求数据的脚本 <?php // header("Content-type:text/html;charset=utf-8&qu ...

  3. react native之使用 Fetch进行网络数据请求

    这是一个单独的页面,可以从其他地方跳转过来. 输入语言关键字,从github检索相关数据 import React, {Component} from 'react'; import { StyleS ...

  4. Android利用Fiddler进行网络数据抓包,手机抓包工具汇总

    Fiddler抓包工具 Fiddler抓包工具很好用的,它可以干嘛用呢,举个简单例子,当你浏览网页时,网页中有段视频非常好,但网站又不提供下载,用迅雷下载你又找不到下载地址,这个时候,Fiddler抓 ...

  5. iOS中GET 和 POST 数据请求

    iOS中GET 和 POST 网络数据请求 同步请求和异步请求的差别: 1.同步请求,有主线程完成网路请求任务,在数据没有请求之前,用户的所有的交互事件应用都无法处理,会造成一种卡顿现象,影响用户体验 ...

  6. Android利用Fiddler进行网络数据抓包,手机抓包工具汇总,使用mono运行filddler

    Fiddler抓包工具 Fiddler抓包工具很好用的,它可以干嘛用呢,举个简单例子,当你浏览网页时,网页中有段视频非常好,但网站又不提供下载,用迅雷下载你又找不到下载地址,这个时候,Fiddler抓 ...

  7. Android利用tcpdump和wireshark抓取网络数据包

    Android利用tcpdump和wireshark抓取网络数据包 主要介绍如何利用tcpdump抓取andorid手机上网络数据请求,利用Wireshark可以清晰的查看到网络请求的各个过程包括三次 ...

  8. Android之MVP模式实现登录和网络数据加载

    MVP简介 相信大家对 MVC 都是比较熟悉了:M-Model-模型.V-View-视图.C-Controller-控制器,MVP作为MVC的演化版本,也是作为用户界面(用户层)的实现模式,那么类似的 ...

  9. Android - 使用Volley请求网络数据

    Android - 使用Volley请求网络数据 Android L : Android Studio 14 个人使用volley的小记,简述使用方法,不涉及volley源码 准备工作 导入Volle ...

随机推荐

  1. Android导入Burp Suite证书抓包HTTPS

    需求 Android APP安全测试时,主要工作分为: APK安全 业务安全 APK安全这里不讨论,我说说业务安全,因为大部分的业务校验逻辑还是放在Servier端,这里就会涉及到网络通信了.因此网络 ...

  2. Mybaits-从零开始-Spring、Spring MVC、MyBatis整合(未万待续)

    Spring.Spring MVC.MyBatis整合(未万待续)

  3. cp -rf 操作时依然会提示覆盖

    在linux上经常会使用cp -rf命令,该命令就是强制覆盖指定目录下的文件,但有时使用该命令依然会提示是否覆盖,cp命令的参数有如下一些: 参数说明: -a:此选项通常在复制目录时使用,它保留链接. ...

  4. Redis 搭建一主二从三哨兵高可用集群

    1.单个redis服务搭建请参考:redis服务搭建 2.在/usr/local下创建目录redis-cluster,并在redis-cluster下创建 6379.6380.6381目录以及data ...

  5. ELK 学习笔记之 elasticsearch head插件安装

    elasticsearch head插件安装: 准备工作: 安装nodejs和npm https://nodejs.org/en/download/ node-v6.11.2-linux-x64.ta ...

  6. MongoDB系列(一):初步理解

    一.简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库 1.易用性 1)MongoDB是一款面向文档的数据库,而不是关系型数据库,因此而有着更好的扩展性. 2)通过在文档中嵌入文档和数组, ...

  7. Int类的129为什么转成byte就变成-127了?

    作为一个java开发人员,接触的基本都是上层的,都是以应用为主,根据业务实现功能,但今天无意间发现了一个小问题,int类型的129转成byte类型变成了-127,我知道是因为位数截取的原因,但是还没有 ...

  8. eventfd(2) 结合 select(2) 源码分析

    eventfd(2) 结合 select(2) 源码分析 本文代码选自内核 4.17 eventfd(2) - 创建一个文件描述符用于事件通知. 使用 源码分析 参考 #include <sys ...

  9. Jmeter中逻辑控制器

    1.ForEach控制器 操作如下: 对应结果: 2.if controller(类似于if语句,根据给定表达式的值决定是否执行该节点下的字节的) 3.交替控制器(根据线程组中的循环次数来设定子节点中 ...

  10. Springboot 系列(十四)迅速启用 HTTPS 加密你的网站

    1. 获取 HTTPS 证书 正常情况下 HTTPS 证书需要从证书授权中心获得,这样获得的证书才具有公信力,也会被各种浏览器客户端所认可.常见的证书品牌如 Symantec,GeoTrustm,Tr ...