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. matlab使用总结2

    1.MATLAB中a./b与a/b的区别以及左除和右除 http://blog.csdn.net/wk119911/article/details/7452411 a=[1 2;3 4]; b=[1 ...

  2. VS 代码整理插件推荐:CodeMaid

    一直在用,觉得很不错,其他插件基本上不用了,所以拿来记录并分享一下.CodeMaid 说明文档CodeMaid 下载安装不用说明了,使用看说明文档就好. CodeMaid和ReSharp类似,开源且免 ...

  3. myeclipse10无法weblogic10.3的问题解决方案

    在完成了myec与wl10的基本配置后,启动报如下错误 Parsing Failure in config.xml: java.lang.AssertionError: java.lang.Class ...

  4. toFixed四舍五入精度校正

    var a = 2.255; var b = a.toFixed(2); console.log(b); 以上代码,按预期正常四舍五入得到结果应该是2.26,但实际返回值为2.25 js浮点数精度作为 ...

  5. [JSOI2009]球队收益

    题目 这题好神啊 我们发现一个球队的总比赛场数是确定的,设第\(i\)支球队一共进行了\(s_i\)场比赛 于是这个球队的收益就是\(c_i\times x^2+d_i(s_i-x)^2\) 我们拆开 ...

  6. 【洛谷】【前缀和+st表】P2629 好消息,坏消息

    [题目描述:] uim在公司里面当秘书,现在有n条消息要告知老板.每条消息有一个好坏度,这会影响老板的心情.告知完一条消息后,老板的心情等于之前老板的心情加上这条消息的好坏度.最开始老板的心情是0,一 ...

  7. 容器内部设置JVM的Heap大小

    容器内部利用脚本来获取容器的CGroup资源限制,并通过设置JVM的Heap大小. Docker1.7开始将容器cgroup信息挂载到容器中,所以应用可以从 /sys/fs/cgroup/memory ...

  8. Oracle create tablespace 创建表空间语法详解

    CREATE [UNDO]  TABLESPACE tablespace_name          [DATAFILE datefile_spec1 [,datefile_spec2] ...... ...

  9. Android7.0调用系统相机拍照、读取系统相册照片+CropImageView剪裁照片

    Android手机拍照.剪裁,并非那么简单 简书地址:[我的简书–T9的第三个三角] 前言 项目中,基本都有用户自定义头像或自定义背景的功能,实现方法一般都是调用系统相机–拍照,或者系统相册–选择照片 ...

  10. less初识

    一种 动态 样式 语言. LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承,运算, 函数. LESS 既可以在 客户端 上运行 (支持IE 6+, Webkit, Firefox),也可以 ...