https://www.cnblogs.com/ButterflyEffect/p/14773840.html
C# Body为form-data file文件上传至第三方接口
1.第三方提供了这么一个API接口,POST后将附件以file文件上传,通过postman工具界面是下面这种样子
Body为form-data类型,不管是文本还是文件,都能在value上填上去
2.C#实现接口调用代码
public static string PostForm(string url, List<FormItemModel> formItems, CookieContainer cookieContainer = null, string refererUrl = null, Encoding encoding = null, int timeOut = 20000)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
#region 初始化请求对象
request.Method = "POST";
request.Timeout = timeOut;
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.KeepAlive = true;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";
if (!string.IsNullOrEmpty(refererUrl))
request.Referer = refererUrl;
if (cookieContainer != null)
request.CookieContainer = cookieContainer;
#endregion
<span class="hljs-built_in">string</span> boundary = <span class="hljs-string">"----"</span> + DateTime.Now.Ticks.ToString(<span class="hljs-string">"x"</span>);<span class="hljs-comment">//分隔符</span>
request.ContentType = <span class="hljs-built_in">string</span>.Format(<span class="hljs-string">"multipart/form-data; boundary={0}"</span>, boundary);
<span class="hljs-comment">//请求流</span>
<span class="hljs-keyword">var</span> postStream = <span class="hljs-keyword">new</span> MemoryStream();
<span class="hljs-meta">#<span class="hljs-meta-keyword">region</span> 处理Form表单请求内容</span>
<span class="hljs-comment">//是否用Form上传文件</span>
<span class="hljs-keyword">var</span> formUploadFile = formItems != <span class="hljs-literal">null</span> && formItems.Count > <span class="hljs-number">0</span>;
<span class="hljs-keyword">if</span> (formUploadFile)
{
<span class="hljs-comment">//文件数据模板</span>
<span class="hljs-built_in">string</span> fileFormdataTemplate =
<span class="hljs-string">"
--"</span> + boundary +
<span class="hljs-string">"
Content-Disposition: form-data; name="{0}"; filename="{1}""</span> +
<span class="hljs-string">"
Content-Type: application/octet-stream"</span> +
<span class="hljs-string">"
"</span>;
<span class="hljs-comment">//文本数据模板</span>
<span class="hljs-built_in">string</span> dataFormdataTemplate =
<span class="hljs-string">"
--"</span> + boundary +
<span class="hljs-string">"
Content-Disposition: form-data; name="{0}""</span> +
<span class="hljs-string">"
{1}"</span>;
<span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> item <span class="hljs-keyword">in</span> formItems)
{
<span class="hljs-built_in">string</span> formdata = <span class="hljs-literal">null</span>;
<span class="hljs-keyword">if</span> (item.IsFile)
{
<span class="hljs-comment">//上传文件</span>
formdata = <span class="hljs-built_in">string</span>.Format(
fileFormdataTemplate,
item.Key, <span class="hljs-comment">//表单键</span>
item.FileName);
}
<span class="hljs-keyword">else</span>
{
<span class="hljs-comment">//上传文本</span>
formdata = <span class="hljs-built_in">string</span>.Format(
dataFormdataTemplate,
item.Key,
item.Value);
}
<span class="hljs-comment">//统一处理</span>
<span class="hljs-built_in">byte</span>[] formdataBytes = <span class="hljs-literal">null</span>;
<span class="hljs-comment">//第一行不需要换行</span>
<span class="hljs-keyword">if</span> (postStream.Length == <span class="hljs-number">0</span>)
formdataBytes = Encoding.UTF8.GetBytes(formdata.Substring(<span class="hljs-number">2</span>, formdata.Length - <span class="hljs-number">2</span>));
<span class="hljs-keyword">else</span>
formdataBytes = Encoding.UTF8.GetBytes(formdata);
postStream.Write(formdataBytes, <span class="hljs-number">0</span>, formdataBytes.Length);
<span class="hljs-comment">//写入文件内容</span>
<span class="hljs-keyword">if</span> (item.FileContent != <span class="hljs-literal">null</span> && item.FileContent.Length > <span class="hljs-number">0</span>)
{
<span class="hljs-keyword">using</span> (<span class="hljs-keyword">var</span> stream = item.FileContent)
{
<span class="hljs-built_in">byte</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-built_in">byte</span>[<span class="hljs-number">1024</span>];
<span class="hljs-built_in">int</span> bytesRead = <span class="hljs-number">0</span>;
<span class="hljs-keyword">while</span> ((bytesRead = stream.Read(buffer, <span class="hljs-number">0</span>, buffer.Length)) != <span class="hljs-number">0</span>)
{
postStream.Write(buffer, <span class="hljs-number">0</span>, bytesRead);
}
}
}
}
<span class="hljs-comment">//结尾</span>
<span class="hljs-keyword">var</span> footer = Encoding.UTF8.GetBytes(<span class="hljs-string">"
--"</span> + boundary + <span class="hljs-string">"--
"</span>);
postStream.Write(footer, <span class="hljs-number">0</span>, footer.Length);
}
<span class="hljs-keyword">else</span>
{
request.ContentType = <span class="hljs-string">"application/x-www-form-urlencoded"</span>;
}
<span class="hljs-meta">#<span class="hljs-meta-keyword">endregion</span></span>
request.ContentLength = postStream.Length;
<span class="hljs-meta">#<span class="hljs-meta-keyword">region</span> 输入二进制流</span>
<span class="hljs-keyword">if</span> (postStream != <span class="hljs-literal">null</span>)
{
postStream.Position = <span class="hljs-number">0</span>;
<span class="hljs-comment">//直接写入流</span>
Stream requestStream = request.GetRequestStream();
<span class="hljs-built_in">byte</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-built_in">byte</span>[<span class="hljs-number">1024</span>];
<span class="hljs-built_in">int</span> bytesRead = <span class="hljs-number">0</span>;
<span class="hljs-keyword">while</span> ((bytesRead = postStream.Read(buffer, <span class="hljs-number">0</span>, buffer.Length)) != <span class="hljs-number">0</span>)
{
requestStream.Write(buffer, <span class="hljs-number">0</span>, bytesRead);
}
<span class="hljs-comment"><span class="hljs-doctag">///</span>/debug</span>
<span class="hljs-comment">//postStream.Seek(0, SeekOrigin.Begin);</span>
<span class="hljs-comment">//StreamReader sr = new StreamReader(postStream);</span>
<span class="hljs-comment">//var postStr = sr.ReadToEnd();</span>
postStream.Close();<span class="hljs-comment">//关闭文件访问</span>
}
<span class="hljs-meta">#<span class="hljs-meta-keyword">endregion</span></span>
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
<span class="hljs-keyword">if</span> (cookieContainer != <span class="hljs-literal">null</span>)
{
response.Cookies = cookieContainer.GetCookies(response.ResponseUri);
}
<span class="hljs-keyword">using</span> (Stream responseStream = response.GetResponseStream())
{
<span class="hljs-keyword">using</span> (StreamReader myStreamReader = <span class="hljs-keyword">new</span> StreamReader(responseStream, encoding ?? Encoding.UTF8))
{
<span class="hljs-built_in">string</span> retString = myStreamReader.ReadToEnd();
<span class="hljs-keyword">return</span> retString;
}
}
}
public class FormItemModel
{
/// <summary>
/// 表单键,request["key"]
/// </summary>
public string Key { set; get; }
/// <summary>
/// 表单值,上传文件时忽略,request["key"].value
/// </summary>
public string Value { set; get; }
/// <summary>
/// 是否是文件
/// </summary>
public bool IsFile
{
get
{
if (FileContent == null || FileContent.Length == 0)
return false;
if (FileContent != null && FileContent.Length > 0 && string.IsNullOrWhiteSpace(FileName))
throw new Exception("上传文件时 FileName 属性值不能为空");
return true;
}
}
/// <summary>
/// 上传的文件名
/// </summary>
public string FileName { set; get; }
/// <summary>
/// 上传的文件内容
/// </summary>
public Stream FileContent { set; get; }
}
模拟post调用
var url = "http://127.0.0.1/testformdata.aspx?aa=1&bb=2&ccc=3";
var log1=@"D: emplog1.txt";
var log2 = @"D: emplog2.txt";
var formDatas = new List<Grass.Net.FormItemModel>();
//添加文件
formDatas.Add(new Grass.Net.FormItemModel()
{
Key="log1",
Value="",
FileName = "log1.txt",
FileContent=File.OpenRead(log1)
});
formDatas.Add(new Grass.Net.FormItemModel()
{
Key = "log2",
Value = "",
FileName = "log2.txt",
FileContent = File.OpenRead(log2)
});
//添加文本
formDatas.Add(new Grass.Net.FormItemModel()
{
Key = "id",
Value = "id-test-id-test-id-test-id-test-id-test-"
});
formDatas.Add(new Grass.Net.FormItemModel()
{
Key = "name",
Value = "name-test-name-test-name-test-name-test-name-test-"
});
//提交表单
var result = PostForm(url, formDatas);
至此引用别人的资料:https://www.cnblogs.com/xiaosuxing/p/13403172.html
3.以上方法读流是通过文件存取的绝对路径去转换为流,进而去请求第三方接口把文件以流的方式上传
如果是文件服务器上的URL,则此方法不能通用,也试过将流转换都不行,最后找到一种思路可行,先将URL下载存到临时文件夹里,再通过以上方法将文件读取成流后上传,代码如下
/// <summary>
/// 根据文件服务器上的地址URL保存文件到临时路径
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static Stream HttpDownload(string url)
{
using (var client = new WebClient())
{
string tempFile = Path.GetTempFileName();
client.DownloadFile(url, tempFile);//下载临时文件
return FileToStream(tempFile, true);//转文件流后删除临时文件夹
}
}
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag"><summary></span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> 文件转流</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag"></summary></span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag"><param name="fileName"></span>文件路径<span class="hljs-doctag"></param></span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag"><param name="isDelete"></span>是否删除临时文件<span class="hljs-doctag"></param></span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag"><returns></span><span class="hljs-doctag"></returns></span></span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Stream <span class="hljs-title">FileToStream</span>(<span class="hljs-params"><span class="hljs-built_in">string</span> fileName, <span class="hljs-built_in">bool</span> isDelete = <span class="hljs-literal">false</span></span>)</span>
{
<span class="hljs-comment">//打开文件</span>
FileStream fileStream = <span class="hljs-keyword">new</span> FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
<span class="hljs-comment">// 读取文件的 byte[]</span>
<span class="hljs-built_in">byte</span>[] bytes = <span class="hljs-keyword">new</span> <span class="hljs-built_in">byte</span>[fileStream.Length];
fileStream.Read(bytes, <span class="hljs-number">0</span>, bytes.Length);
fileStream.Close();
<span class="hljs-comment">// 把 byte[] 转换成 Stream</span>
Stream stream = <span class="hljs-keyword">new</span> MemoryStream(bytes);
<span class="hljs-keyword">if</span> (isDelete)
{
File.Delete(fileName);<span class="hljs-comment">//删除临时文件</span>
}
<span class="hljs-keyword">return</span> stream;
}