• 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
    
                string boundary = "----" + DateTime.Now.Ticks.ToString("x");//分隔符
                request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
                //请求流
                var postStream = new MemoryStream();
                #region 处理Form表单请求内容
                //是否用Form上传文件
                var formUploadFile = formItems != null && formItems.Count > 0;
                if (formUploadFile)
                {
                    //文件数据模板
                    string fileFormdataTemplate =
                        "
    --" + boundary +
                        "
    Content-Disposition: form-data; name="{0}"; filename="{1}"" +
                        "
    Content-Type: application/octet-stream" +
                        "
    
    ";
                    //文本数据模板
                    string dataFormdataTemplate =
                        "
    --" + boundary +
                        "
    Content-Disposition: form-data; name="{0}"" +
                        "
    
    {1}";
                    foreach (var item in formItems)
                    {
                        string formdata = null;
                        if (item.IsFile)
                        {
                            //上传文件
                            formdata = string.Format(
                                fileFormdataTemplate,
                                item.Key, //表单键
                                item.FileName);
                        }
                        else
                        {
                            //上传文本
                            formdata = string.Format(
                                dataFormdataTemplate,
                                item.Key,
                                item.Value);
                        }
    
                        //统一处理
                        byte[] formdataBytes = null;
                        //第一行不需要换行
                        if (postStream.Length == 0)
                            formdataBytes = Encoding.UTF8.GetBytes(formdata.Substring(2, formdata.Length - 2));
                        else
                            formdataBytes = Encoding.UTF8.GetBytes(formdata);
                        postStream.Write(formdataBytes, 0, formdataBytes.Length);
    
                        //写入文件内容
                        if (item.FileContent != null && item.FileContent.Length > 0)
                        {
                            using (var stream = item.FileContent)
                            {
                                byte[] buffer = new byte[1024];
                                int bytesRead = 0;
                                while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
                                {
                                    postStream.Write(buffer, 0, bytesRead);
                                }
                            }
                        }
                    }
                    //结尾
                    var footer = Encoding.UTF8.GetBytes("
    --" + boundary + "--
    ");
                    postStream.Write(footer, 0, footer.Length);
    
                }
                else
                {
                    request.ContentType = "application/x-www-form-urlencoded";
                }
                #endregion
    
                request.ContentLength = postStream.Length;
    
                #region 输入二进制流
                if (postStream != null)
                {
                    postStream.Position = 0;
                    //直接写入流
                    Stream requestStream = request.GetRequestStream();
    
                    byte[] buffer = new byte[1024];
                    int bytesRead = 0;
                    while ((bytesRead = postStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        requestStream.Write(buffer, 0, bytesRead);
                    }
    
                    ////debug
                    //postStream.Seek(0, SeekOrigin.Begin);
                    //StreamReader sr = new StreamReader(postStream);
                    //var postStr = sr.ReadToEnd();
                    postStream.Close();//关闭文件访问
                }
                #endregion
    
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                if (cookieContainer != null)
                {
                    response.Cookies = cookieContainer.GetCookies(response.ResponseUri);
                }
    
                using (Stream responseStream = response.GetResponseStream())
                {
                    using (StreamReader myStreamReader = new StreamReader(responseStream, encoding ?? Encoding.UTF8))
                    {
                        string retString = myStreamReader.ReadToEnd();
                        return 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);//转文件流后删除临时文件夹
                }
            }
    
            /// <summary>
            /// 文件转流
            /// </summary>
            /// <param name="fileName">文件路径</param>
            /// <param name="isDelete">是否删除临时文件</param>
            /// <returns></returns>
            public static Stream FileToStream(string fileName, bool isDelete = false)
            {
    
                //打开文件
    
                FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
    
                // 读取文件的 byte[]
    
                byte[] bytes = new byte[fileStream.Length];
    
                fileStream.Read(bytes, 0, bytes.Length);
    
                fileStream.Close();
    
                // 把 byte[] 转换成 Stream
    
                Stream stream = new MemoryStream(bytes);
                if (isDelete)
                {
                    File.Delete(fileName);//删除临时文件
                }
                return stream;
    
            }
    
    人说,如果你很想要一样东西,就放它走 。如果它回来找你,那么它永远都是你的。要是它没有回来,那么不用再等了,因为它根本就不是你的。 ——伊恩·麦克尤恩 ​
  • 相关阅读:
    今天开通我的博客
    在ArcGIS中,利用“行政单元面积权重法”实现人口数据格网化
    ArcGIS 下的水文分析
    常用计数器的verilog实现(binary、gray、onehot、LFSR、环形、扭环形)
    简单组合逻辑电路的verilog实现(包括三态门、38译码器、83优先编码器、8bit奇偶校验器)
    乘法器的verilog实现(并行、移位相加、查找表)
    简单时序逻辑电路的verilog实现,包括D触发器、JK触发器、锁存器、寄存器、
    简单ALU(算术逻辑单元)的verilog实现
    ubuntu下安装virtualbox 错误及解决办法
    C++单例模式对象的控制释放分析
  • 原文地址:https://www.cnblogs.com/ButterflyEffect/p/14773840.html
Copyright © 2020-2023  润新知