C# 使用HttpWebRequest显示文件上载进度

C# 使用HttpWebRequest显示文件上载进度,c#,.net,C#,.net,我正在试图弄清楚如何执行多部分/表单数据put请求,并能够获得文件的上传进度。我遇到的问题是直到request.GetResponse()才发送请求;在发送前使我的写作进度达到100%。我尝试过谷歌搜索,发现有人使用request.SendChunked=true解决了这个问题;和request.AllowWriteStreamBuffering=false;但这似乎没有任何区别。我已经看到一些人发表了关于这一点的帖子,但还没有找到一个我能找到的解决方案。这是我的尝试。你知道我能做些什么来解决这

我正在试图弄清楚如何执行多部分/表单数据put请求,并能够获得文件的上传进度。我遇到的问题是直到request.GetResponse()才发送请求;在发送前使我的写作进度达到100%。我尝试过谷歌搜索,发现有人使用request.SendChunked=true解决了这个问题;和request.AllowWriteStreamBuffering=false;但这似乎没有任何区别。我已经看到一些人发表了关于这一点的帖子,但还没有找到一个我能找到的解决方案。这是我的尝试。你知道我能做些什么来解决这个问题吗

class Program
{
    private static float _progressBar;

    static async Task Main(string[] args)
    {
        Console.WriteLine("hello");
        // https://postman-echo.com/put
        var response =  ExecutePutCommand("C:/temp/zipfile.zip",
            "https://postman-echo.com/put", "weef");
     }

    protected static string ExecutePutCommand(string filename, string uriStr, string stringToAdd)
    {
        try
        {
            const string authCookie = "";
            byte[] fileBytes = File.ReadAllBytes(filename);
            //
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uriStr);
            request.SendChunked = true;
            request.PreAuthenticate = true;
            request.AllowWriteStreamBuffering = false;
            request.KeepAlive = true;
            request.ProtocolVersion = HttpVersion.Version11;

            string boundary = System.Guid.NewGuid().ToString();
            //
            request.ContentType = string.Format("multipart/form-data;boundary={0}", boundary);
            request.Method = "PUT";
            //request.Headers["Cookie"] = authCookie;

            // Build Contents for Post
            string header = string.Format("--{0}", boundary);
            string footer = header + "--";
            // string builders are for the text above and below the file - file is kept in its original format.
            StringBuilder contents = new StringBuilder();
            StringBuilder contents2 = new StringBuilder();

            // Zip File
            contents.AppendLine(header);
            contents.AppendLine(
                string.Format("Content-Disposition:form-data; name=\"filefield\"; filename=\"{0}\"",
                    filename));
            contents.AppendLine("Content-Type: application/x-zip-compressed");
            contents.AppendLine();

            // file goes here... then contents 2

            contents2.AppendLine();
            // Form Field 1
            contents2.AppendLine(header);
            contents2.AppendLine("Content-Disposition:form-data; name=\"stringToAdd\"");
            contents2.AppendLine();
            contents2.AppendLine(stringToAdd);
            // Form Field 2
            // Footer
            contents2.AppendLine(footer);

            // This is sent to the Put
            byte[] bytes = Encoding.UTF8.GetBytes(contents.ToString());
            byte[] bytes2 = Encoding.UTF8.GetBytes(contents2.ToString());
            byte[] formData = bytes.Concat(fileBytes).Concat(bytes2).ToArray();
           
            // calculate size of the stream
            request.ContentLength = bytes.Length + fileBytes.Length + bytes2.Length;

            byte[] buffer = new byte[4096];
            int count = 0;
            int length = 0;
            Stopwatch sw = new Stopwatch();
            sw.Start();
            //request.Proxy = null;
            using (Stream requestStream = request.GetRequestStream())
            {
                using (Stream inputStream = new MemoryStream(formData))
                {

                    while ((count = inputStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        requestStream.Write(buffer, 0, count);
                        length += count;

                        _progressBar = (float)length / request.ContentLength;
                        //Console.WriteLine(_progressBar);
                    }
                }
            }
            sw.Stop();
           
            WebResponse resp =  request.GetResponse();
            Stopwatch sw2 = new Stopwatch();
            sw.Start();
            using (Stream stream = resp.GetResponseStream())
            {
                StreamReader respReader = new StreamReader(stream);
                sw2.Stop();
                return respReader.ReadToEnd();
            }
        }
        catch (Exception e)
        {

            Debug.WriteLine(e.ToString());
            return String.Empty;
        }

        return null;
    }
}
如果我从命令行执行curl,它将启动一个tickingpload进度文本,显示已上载的mb数和预计剩余时间,因此邮递员服务器似乎支持此功能:

C:\temp>curl-v-X PUT-F“filefield=@C:\temp\zipfile.zip“-F”field2=blah”>log.txt %总接收百分比%x平均速度时间电流 数据加载上载总左速度 0 0 0 0 0 0 0--:-:-:-:-:-:---:---0*正在尝试107.23.124.180

  • TCP_节点集
  • 连接到postman-echo.com(107.23.124.180)端口443(#0)
  • schannel:postman-echo.com端口443的SSL/TLS连接(步骤1/3)
  • schannel:正在检查服务器证书吊销
  • 发送初始握手数据:发送181字节
  • schannel:发送的初始握手数据:发送181字节
  • schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
  • schannel:无法接收握手,需要更多数据
  • schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
  • schannel:加密数据得到4096个
  • schannel:加密数据缓冲区:偏移量4096长度4096
  • schannel:加密数据长度:4030
  • schannel:加密数据缓冲区:偏移量4030长度4096
  • schannel:收到不完整的消息,需要更多数据
  • schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
  • 沙内尔:加密的数据有1024个
  • schannel:加密数据缓冲区:偏移量5054长度5054
  • schannel:加密数据长度:200
  • schannel:加密数据缓冲区:偏移量200长度5054
  • schannel:收到不完整的消息,需要更多数据
  • schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
  • 沙内尔:加密数据得到147
  • schannel:加密数据缓冲区:偏移量347长度5054
  • 发送下一次握手数据:发送126字节
  • schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
  • 沙内尔:加密数据得到258
  • schannel:加密数据缓冲区:偏移量258长度5054
  • schannel:SSL/TLS握手完成
  • schannel:postman-echo.com端口443的SSL/TLS连接(步骤3/3)
  • schannel:会话缓存中存储的凭据句柄
PUT/PUT HTTP/1.1 主持人:postman-echo.com 用户代理:curl/7.55.1 接受:/ 内容长度:11472946 预期:100人继续 内容类型:多部分/表单数据;边界=---------------------------3AFF00F52D07DF7

  • schannel:客户端想要读取102400字节
  • schannel:encdata_缓冲区大小调整为103424
  • schannel:加密数据缓冲区:偏移量0长度103424
  • 沙内尔:加密数据得到54
  • schannel:加密数据缓冲区:偏移量54长度103424
  • schannel:解密的数据长度:25
  • schannel:已添加解密数据:25
  • schannel:缓存的解密数据:偏移量25长度102400
  • schannel:加密数据缓冲区:偏移量0长度103424
  • schannel:解密数据缓冲区:偏移量25长度102400
  • schannel:schannel_recv清理
  • schannel:已解密的数据返回25
  • schannel:解密的数据缓冲区:偏移量0长度102400

3110.9M 0 0 31 3552k 0 208k 0:00:53 0:00:17 0:00:36 317k

Http具有流模式(1.0)和块模式(1.1)。当建立连接时,客户机和服务器之间会进行协商,以获得公共传输模式。仅当服务器支持区块模式时,区块模式才起作用。尝试向请求中添加以下内容:request.ProtocolVersion=HttpVersion.Version11;谢谢你的建议,但遗憾的是,这没什么区别。我更新了我的代码以显示我如何使用您的建议。如果我从命令行做一个curl,我可以得到一个进度表,所以看起来postmanecho服务器支持这个。C:\temp>curl-X PUT-F“filefield=@C:\temp\zipfile.zip“-F”field2=blah“>log.txt%总计%已接收%Xferd平均速度时间当前数据加载上载总计已用左速度810.9M 08944k 0236k 0:00:47 0:00:04 0:00:43 218k^CHttp具有流模式(1.0)块模式(1.1)。当建立连接时,客户机和服务器之间会进行协商,以获得公共传输模式。仅当服务器支持区块模式时,区块模式才起作用。尝试向请求中添加以下内容:request.ProtocolVersion=HttpVersion.Version11;谢谢你的建议,但遗憾的是,这没什么区别。我更新了我的代码以显示我如何使用您的建议。如果我从命令行做一个curl,我可以得到一个进度表,所以看起来postmanecho服务器支持这个。C:\temp>curl-X PUT-F“filefield=@C:\temp\zipfile.zip“-F”field2=blah”>log.txt%总计%已接收%Xferd平均速度时间当前数据加载上载总计已用左速度810.9M 08944k 0236k 0:00:47 0:00:04 0:00:43 218k^C