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表单请求的更多相关文章

  1. 模拟form表单请求上传文件

    发请求 public string CameraFileUpload(string url,string path,string serverPath,string uploadfileName) { ...

  2. nodejs 模拟form表单上传文件

    使用nodejs来模拟form表单进行文件上传,可以同时上传多个文件. 以前项目里有这个方法,最近在客户那里出问题了,同事说,这个方法从来就没管用过,SO,用了一天时间把这个方法给搞出来了(觉得花费的 ...

  3. js模拟form表单提交数据, js模拟a标签点击跳转,避开使用window.open引起来的浏览器阻止问题

    js模拟form表单提交数据, js模拟a标签点击跳转,避开使用window.open引起来的浏览器阻止问题 js模拟form表单提交数据源码: /** * js模拟form表单提交 * @param ...

  4. js_ajax模拟form表单提交_多文件上传_支持单个删除

    需求场景: 用一个input type="file"按钮上传多张图片,可多次上传,可单独删除,最后使用ajax模拟form表单提交功能提交到指定方法中: 问题:由于只有一个file ...

  5. Linux curl 模拟form表单提交信息和文件

    Linux curl 模拟form表单提交信息和文件   curl是一个命令行方式下传输数据的开源传输工具,支持多种协议:FTP.HTTP.HTTPS.IMAP.POP3.TELNET等,功能超级强大 ...

  6. java如何区分是form表单请求,还是ajax请求

    requestType = request.getHeader("X-Requested-With");                 if(requestType==null) ...

  7. 使用HttpClient 传送form 表单的请求

    在项目中用到了,需要使用HttpClient 进行模拟表单传送form 表单的需求,在平常的项目中,大概都是传送json串的样式需求,但是如何才能给对应的服务器传送一个form 表单呢? 这就需要了N ...

  8. Ajax模拟Form表单提交,含多种数据上传

    ---恢复内容开始--- Ajax提交表单.使用FormData提交表单数据和上传的文件(这里的后台使用C#获取,你可以使用Java一样获取) 有时候前台的数据提交到后台,不想使用form表单上传,希 ...

  9. jquery模拟form表单提交并新打开页面

    /** * form表单提交本页面打开 * @param url * @param params */ function postCurrent(url,params){ var form = $(& ...

随机推荐

  1. 如何把SQL Server中一个表,一个存储过程,一个视图等改为系统表,系统存储过程,系统视图等

    使用如下存储过程即可: EXEC sys.sp_MS_marksystemobject '[dbo].[TableNameToSystem]' 其中"[dbo].[TableNameToSy ...

  2. MySQL主从复制日常管理维护篇

    日常工作中,我们需要经常进行一些监控和管理维护工作,以便能及时发现一些复制中的问题,并尽快解决,以此来保证复制能够正常工作 1.查看从库状态 MySQL [(none)]> show slave ...

  3. wx.aui.AuiManager部分/布局翻译

    wx.aui.AuiManager wx.aui.AuiManager 是AUI框架类中的主要类 wx.aui.AuiManager管理于指定的wx.Frame相关联的窗口,通过使用窗口的wx.aui ...

  4. js判断360浏览器 兼容模式IE版本

    var ms_ie = false; var ua = window.navigator.userAgent.toLowerCase(); var old_ie = ua.indexOf('MSIE' ...

  5. BZOJ 1834 网络扩容 最大流+最小费用流

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1834 题目大意: 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是 ...

  6. ACM模拟赛

    今天是毕业的学长给高二的同学测试.组队比赛,ACM赛制,于是就愉快的和学姐一队啦. 看到英文题面感到恐慌,不过好在不难读懂. A:并没有什么技术含量的模拟题: B:字符串题,给定一些比赛和每个队胜利的 ...

  7. CentOS7下账号与用户

    /etc/passwd用户记录文件,文件记录着ID和账号与一般身份用户的对应关系 用户至少会有2个ID,用户ID(UserID简UID)和用户组ID(GroupID简GID). /etc/group用 ...

  8. JAVA框架Struts2 数据封装

    一.strust2封装数据包含二部分: 数据在到Action类的时候,会经过拦截器,拦截器会有很多功能:比如数据封装.类型转换等. 我可以查看下strust-default.xml文件,看那些拦截器默 ...

  9. JAVA 第二周学习总结

    20175308 2018-2019-2 <Java程序设计>第二周学习总结 教材学习内容总结: 第二章学习内容: 1.认识标识符与关键字 2.java的八种数据类型,着重记好精度由高到低 ...

  10. Python3.2-re模块之常用正则记录

    python的re模块是个很好的模块,这里简单记录下自己编写的几个有用的正则: 1:邮箱匹配: gReMailbox = re.compile(r'([\w\.\-+]+@[\w\-]+(?:\.[\ ...