zoukankan      html  css  js  c++  java
  • C# Body为form-data file文件上传至第三方接口 http请求

    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">"
    --"</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> &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">"
    --"</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">&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;
    
        }
    

  • 相关阅读:
    痞子衡嵌入式:MCUBootFlasher v3.0发布,为真实的产线操作场景而生
    架构设计 | 分布式体系下,服务分层监控策略
    Hadoop框架:单服务下伪分布式集群搭建
    大数据简介,技术体系分类整理
    架构设计 | 基于Seata中间件,微服务模式下事务管理
    编程体系结构(03):Java集合容器
    SpringBoot2 集成日志,复杂业务下的自定义实现
    结构与算法(02):队列和栈结构
    架构设计 | 基于消息中间件,图解柔性事务一致性
    编程体系结构(02):Java异常体系
  • 原文地址:https://www.cnblogs.com/sunny3158/p/14979271.html
Copyright © 2011-2022 走看看