通过C#的HttpClient模拟form表单请求
post提交表单一般无非是一般text文本和文件类型,如下
<input type="file"/>
<input type="text"/>
如果模拟post提交表单的过程(类似于HTML表单提交),该怎么做呢
这里就需要用到HttpClietn类
首先我们需要一个类去包装这些需要上载的数据,例如
/// <summary>
/// 包装Data数据的Model
/// </summary>
public class SendData
{
/// <summary>
/// 多个文件的
/// </summary>
public List<HttpPostedFileBase> FileList { get; set; } /// <summary>
/// 单个文件
/// </summary>
public HttpPostedFileBase File{ get; set; }
/// <summary>
/// 字节类型
/// </summary>
public byte[] ByteBinary { get; set; } /// <summary>
/// long类型
/// </summary>public long IconId { get; set; } /// <summary>
/// 字符串类型
/// </summary>public string Title { get; set; }
/// <summary>
/// 时间类型
/// </summary>public DateTime PushTime { get; set; } /// <summary>
/// bool类型
/// </summary>public bool PushNow { get; set; }
/// <summary>
/// long的集合类型
/// </summary>
List<long> TestLong { get; set; } = new List<long> { , , , , , }; /// <summary>
/// string的集合类型
/// </summary>
List<string> TestString { get; set; } = new List<string> {"","","" }; }
SendToWebByHttpClient("www.....",new SendData{
FileList =要提交的数据,
File=要提交的数据,
ByteBinary=要提交的数据,
.
.
.
.
. })
请求帮助
/// <summary> 模拟表单请求/liuyl/2017/09/1 /// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="value"></param>
/// <returns></returns>
public static ErrorCode SendToWebByHttpClient<T>(string url, T value)
{
var modelType = typeof(T);
using (var client = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
//遍历SendData的所有成员
foreach (var item in modelType.GetProperties())
{
HttpContent content;
//文件的处理(这里需要特别注意,流只能读取一次,因为读取之后会把Stream.Positon(当前流中的位置)置为最后读取的位置,除非置为0,第二次才可读到)
if (item.PropertyType == typeof(HttpPostedFileBase) && item.GetValue(value) != null)
{
#region Stream请求
//Stream塞进Content会会导致读取这个流,所以之后不能再第二次利用
var model = (HttpPostedFileBase)item.GetValue(value);
content = new StreamContent(model.InputStream, model.ContentLength);
content.Headers.ContentType = MediaTypeHeaderValue.Parse(model.ContentType);//ContentType必须赋值,否则文件接收不到此属性
content.Headers.ContentLength = model.ContentLength;//ContentLength可不显式的赋值,会自动读取给StreamContent的内容长度
formData.Add(content, item.Name, model.FileName);//文件类型,第三个参数必须要赋值,否则不认为这是一个文件 #endregion #region 字节方式请求
//var model = (HttpPostedFileBase)item.GetValue(value);
//MemoryStream fileTarget = new MemoryStream();
//model.InputStream.CopyTo(fileTarget);
//content = new ByteArrayContent(fileTarget.ToArray());
//content.Headers.ContentType = MediaTypeHeaderValue.Parse(model.ContentType);
//content.Headers.ContentLength = model.ContentLength;
//formData.Add(content, item.Name, model.FileName); #endregion
}
//文件的处理
else if (item.PropertyType == typeof(HttpPostedFileWrapper) && item.GetValue(value) != null)
{
#region Stream请求
var model = (HttpPostedFileWrapper)item.GetValue(value);
content = new StreamContent(model.InputStream, model.ContentLength);
content.Headers.ContentType = MediaTypeHeaderValue.Parse(model.ContentType);
content.Headers.ContentLength = model.ContentLength;
formData.Add(content, item.Name, model.FileName); #endregion
#region 字节方式请求
//var model = (HttpPostedFileWrapper)item.GetValue(value);
//MemoryStream fileTarget = new MemoryStream();
//model.InputStream.CopyTo(fileTarget);
//content = new ByteArrayContent(fileTarget.ToArray());
//content.Headers.ContentType = MediaTypeHeaderValue.Parse(model.ContentType);
//content.Headers.ContentLength = model.ContentLength;
//formData.Add(content, item.Name, model.FileName); #endregion }
//文件集合的处理
else if (item.PropertyType == typeof(List<HttpPostedFileBase>) && item.GetValue(value) != null)
{
foreach (var child in ((List<HttpPostedFileBase>)item.GetValue(value)))
{
#region Stream请求
content = new StreamContent(child.InputStream, child.ContentLength);
content.Headers.ContentType = MediaTypeHeaderValue.Parse(child.ContentType);
content.Headers.ContentLength = child.ContentLength;
formData.Add(content, item.Name, child.FileName);
#endregion #region 字节方式请求
//MemoryStream fileTarget = new MemoryStream();
//child.InputStream.CopyTo(fileTarget);
//content = new ByteArrayContent(fileTarget.ToArray());
//content.Headers.ContentType = MediaTypeHeaderValue.Parse(child.ContentType);
//content.Headers.ContentLength = child.ContentLength;
//formData.Add(content, item.Name, child.FileName); #endregion
}
}
//如果执意响应方是接收字节类型,那传输时不能用ByteArrayContent去填充,否则接收方认为这是一个非法数据,故要传base64格式,接收方会自动把base64转成字节接收
else if (item.PropertyType == typeof(byte[]) && item.GetValue(value) != null)
{
content = new StringContent(Convert.ToBase64String((byte[])item.GetValue(value)));
formData.Add(content, item.Name);
}
//其他类型统一按字符串处理(DateTime,Enum;long ;bool;int...)
else if (item.GetValue(value) != null && (item.PropertyType != typeof(byte[]) || item.PropertyType != typeof(HttpPostedFileBase)))
{
content = new StringContent(((string)item.GetValue(value).ToString()));
formData.Add(content, item.Name);
}
} var response = client.PostAsync(url, formData).Result; if (!response.IsSuccessStatusCode)
{
//以下根据自己业务处理返回值
var obj = JsonHandler.DeserializeObject<BaseViewModel>(response.ToString());
if (obj != null)
{
var result = obj.ErrResult;
if (result.ErrorCode != ErrorCode.OK)
{
foreach (var message in result.Messages)
{
_Error += message;
}
return result.ErrorCode;
}
}
}
return ErrorCode.OK;
}
}
partial class InternalController:Controller
{
/// <summary>
/// 接收方
/// </summary>
/// <param name="model"></param>
/// <returns>HTTP200</returns>
[HttpPost]
[ValidateInput(false)]//忽略安全检查,要配合在<system.web>中加入<httpRuntime requestValidationMode =“2.0”/>方可启用,详情参考:了解MVC的请求验证
public ActionResult AddOfficialNews(SendData model)
{
try
{
if (!ModelState.IsValid)
return SendJsonResult(ErrorCode.InvalidOperation);
.....
}
}
}
需要特别注意(特别注意点在请求帮助类中已用黄底背景标注):
如果是上传的文件类型,一定不能在塞入StreamContent等之前进行过读取操作,否则此处将读不到流数据
参考:
https://stackoverflow.com/questions/16416601/c-sharp-httpclient-4-5-multipart-form-data-upload
通过C#的HttpClient模拟form表单请求的更多相关文章
- 模拟form表单请求上传文件
发请求 public string CameraFileUpload(string url,string path,string serverPath,string uploadfileName) { ...
- nodejs 模拟form表单上传文件
使用nodejs来模拟form表单进行文件上传,可以同时上传多个文件. 以前项目里有这个方法,最近在客户那里出问题了,同事说,这个方法从来就没管用过,SO,用了一天时间把这个方法给搞出来了(觉得花费的 ...
- js模拟form表单提交数据, js模拟a标签点击跳转,避开使用window.open引起来的浏览器阻止问题
js模拟form表单提交数据, js模拟a标签点击跳转,避开使用window.open引起来的浏览器阻止问题 js模拟form表单提交数据源码: /** * js模拟form表单提交 * @param ...
- js_ajax模拟form表单提交_多文件上传_支持单个删除
需求场景: 用一个input type="file"按钮上传多张图片,可多次上传,可单独删除,最后使用ajax模拟form表单提交功能提交到指定方法中: 问题:由于只有一个file ...
- Linux curl 模拟form表单提交信息和文件
Linux curl 模拟form表单提交信息和文件 curl是一个命令行方式下传输数据的开源传输工具,支持多种协议:FTP.HTTP.HTTPS.IMAP.POP3.TELNET等,功能超级强大 ...
- java如何区分是form表单请求,还是ajax请求
requestType = request.getHeader("X-Requested-With"); if(requestType==null) ...
- 使用HttpClient 传送form 表单的请求
在项目中用到了,需要使用HttpClient 进行模拟表单传送form 表单的需求,在平常的项目中,大概都是传送json串的样式需求,但是如何才能给对应的服务器传送一个form 表单呢? 这就需要了N ...
- Ajax模拟Form表单提交,含多种数据上传
---恢复内容开始--- Ajax提交表单.使用FormData提交表单数据和上传的文件(这里的后台使用C#获取,你可以使用Java一样获取) 有时候前台的数据提交到后台,不想使用form表单上传,希 ...
- jquery模拟form表单提交并新打开页面
/** * form表单提交本页面打开 * @param url * @param params */ function postCurrent(url,params){ var form = $(& ...
随机推荐
- 破解 jar 包之直接修改 .class 文件方式
一.常规 JAVA 软件破解流程 先讲一下常规jar包的破解流程. 1. 快速定位. 1) 通过procmon监控相关软件,查看程序都访问了些啥. 2) 用jd-gu ...
- 报错:java.net.bindexception: address already in use: jvm_bind:8080
原因:8080端口被占用 这说明80端口(该端口是Tomcat的监听端口)已经被其他程序占用,先用命令提示符 " netstat -ano " 命令显示端口状态,再在结果中找到端口 ...
- python容错
#try: except: else: #为什么叫容错呢,先说说错误,这里说的错误并不是因为马虎或者什么原因在脚本中留下的bug,这个不能容掉,所谓容掉就是略过这个错误,要在测试时候发现并修正,需要容 ...
- 【转】Linux思维导图
[原文]https://www.toutiao.com/i6591690511763898888/ 1.Linux学习路径: 2.Linux桌面介绍: 3.FHS(文件系统目录标准): 4.Linux ...
- win7X64位安装mysql-5.7.16
今天尝试在win7系统中安装mysql,发现过程有点复杂,不过还好已经成功安装,写个博客纪念一下,顺便可以帮助大家. 1.在官网上面下载mysql, 注意:一定要下载对应的版本,第一次下载的是最下面一 ...
- tp查询顺序
tp竟然可以跟据商品的id来进行排序查询的数据 记一些php中排序: sort()方法一维索引数组进行值升序排序 rsort()方法一维索引数组进行值降序排序 unsort()方法负责编写自定义排序操 ...
- sql点滴44—mysql忘记root密码
1. 首先检查mysql服务是否启动,若已启动则先将其停止服务,可在开始菜单的运行,使用命令: net stop mysql 打开第一个cmd1窗口,切换到mysql的bin目录,运行命令: mysq ...
- DevExpress12、DocumentManager
DocumentManager控件 你用过Photoshop吗?里面每打开一个照片,就有一个小窗体承载这个照片,你可以在这些小窗体间切换,最小化.最大化.排列窗体, 这些操作都在Photoshop的大 ...
- p,np,npc,np难问题,确定图灵机与非确定图灵机
本文转自豆瓣_燃烧的影子 图灵机与可计算性 图灵(1912~1954)出生于英国伦敦,19岁进入剑桥皇家学院研究量子力学和数理逻辑.1935年,图灵写出了"论高斯误差函数"的论文, ...
- 【Ansible 文档】【译文】Ad-Hoc 命令介绍
Introduction To Ad-Hoc Commands Ad-Hoc命令介绍 下面的例子展示了如何使用 /usr/bin/ansible 来运行ad hoc任务. 什么是ad hoc命令? 一 ...