sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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> &amp;&amp; formItems.Count &gt; <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">"\r\n--"</span> + boundary +
                <span class="hljs-string">"\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\""</span> +
                <span class="hljs-string">"\r\nContent-Type: application/octet-stream"</span> +
                <span class="hljs-string">"\r\n\r\n"</span>;
            <span class="hljs-comment">//文本数据模板</span>
            <span class="hljs-built_in">string</span> dataFormdataTemplate =
                <span class="hljs-string">"\r\n--"</span> + boundary +
                <span class="hljs-string">"\r\nContent-Disposition: form-data; name=\"{0}\""</span> +
                <span class="hljs-string">"\r\n\r\n{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> &amp;&amp; item.FileContent.Length &gt; <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">"\r\n--"</span> + boundary + <span class="hljs-string">"--\r\n"</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:\temp\log1.txt";
var log2 = @"D:\temp\log2.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">&lt;summary&gt;</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">&lt;/summary&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="fileName"&gt;</span>文件路径<span class="hljs-doctag">&lt;/param&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="isDelete"&gt;</span>是否删除临时文件<span class="hljs-doctag">&lt;/param&gt;</span></span>
    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span><span class="hljs-doctag">&lt;/returns&gt;</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;

    }

posted on 2021-07-06 22:14  sunny123456  阅读(1216)  评论(0编辑  收藏  举报