通过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 = $(& ...
随机推荐
- 大于2t的磁盘分区,并格式化ext4挂载
1:MBR分区表:(MBR含义:主引导记录) 所支持的最大卷:2T (T; terabytes,1TB=1024GB) 对分区的设限:最多4个主分区或3个主分区加一个扩展分区. 2:GPT分区表:(G ...
- JS里设定延时
使用SetInterval和设定延时函数setTimeout 很类似.setTimeout 运用在延迟一段时间,再进行某项操作. setTimeout("function",tim ...
- python模拟自动登录网站(urllib2)
不登录打开网页: import urllib2 request = urllib2.Request('http://www.baidu.com') response = urllib2.urlopen ...
- 自动代码质量分析(GitLab+JenKins+SonarQube)
自动代码质量分析(GitLab+JenKins+SonarQube) 1.需求场景 开发提交代码自动执行代码质量分析. 2.所需应用 GitLab,JenKins,SonarQube 3.架构图 4. ...
- FinalShell使用---Xshell的良心国产软件
最近发现了一款同类产品FinalShell,还是一块良心国货.初步体验了一下,确实是良心之作.且免费(通用版),支持国货. FinalShell是一体化的的服务器,网络管理软件,不仅是ssh客户端,还 ...
- Linux yum源详解
软件包安装方式 0.默认从官网下载包(国内,雅虎,网易,阿里云) cat /etc/yum.repos.d/rhel-source.repo [yum文件目录--redhat6版] [ ...
- 1.2环境的准备(二)之Pycharm的安装和使用
目录: 1.Pycharm的安装 2.Pycharm的使用 (一)pycharm的安装: (1)官网下载:(分为两个版本,专业版和社区版,社区版就足够我们学习用的)https://www.jetbra ...
- Spring Boot 集成 thymeleaf 模版引擎
Spring Boot 建议使用 HTML 来完成动态页面.Spring Boot 提供了大量的模版引擎,包括 Thymeleaf.FreeMarker.Velocity等. Spring Boot ...
- 【Alpha 冲刺】 9/12
今日任务总结 人员 今日原定任务 完成情况 遇到问题 贡献值 胡武成 完善API文档,并初步使用SpringMVC产生编写部分API 已完成 孙浩楷 完成课程通知页面(及发布通知的弹窗) 已完成 胡冰 ...
- python闭包,看不懂请揍我
什么是闭包? 闭包就是一个个内嵌函数+内嵌函数里面引用了外部变量+返回这个内嵌函数(一般是这样) 为什么使用闭包? 有点类似与函数模板?.. 举一个实际的例子: class people: name ...