上传带有进度跟踪的文件(带参数的HttpWebRequest POST) [英] Uploading file with progress tracking (HttpWebRequest POST with parameters)

查看:223
本文介绍了上传带有进度跟踪的文件(带参数的HttpWebRequest POST)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有方法 HttpUploadFile 用一些字符串参数上传图片:

  public static void HttpUploadFile(string url,string file,string paramName,string contentType,NameValueCollection nvc)
{
Console.Write(string.Format(Upload {0} to {1} ,file,url));
string border =---------------------------+ DateTime.Now.Ticks.ToString(x);

byte [] boundarybytes = System.Text.Encoding.ASCII.GetBytes(\r\\\
--+ boundary +\r\\\
);
byte [] omg = boundarybytes;
HttpWebRequest wr =(HttpWebRequest)WebRequest.Create(url);
wr.ContentType =multipart / form-data; boundary =+ boundary;
wr.Method =POST;
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;

流rs = wr.GetRequestStream();

string formdataTemplate =Content-Disposition:form-data; name = \{0} \\r\\\
\r\\\
{1};
foreach(string key in nvc.Keys)
{
rs.Write(boundarybytes,0,boundarybytes.Length);
字符串formitem = string.Format(formdataTemplate,key,nvc [key]);
byte [] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);

rs.Write(formitembytes,0,formitembytes.Length);
}
rs.Write(boundarybytes,0,boundarybytes.Length);

string headerTemplate =Content-Disposition:form-data; name = \{0} \; filename = \{1} \\r\\\
Content-键入:{2} \r\\\
\r\\\
;
string header = string.Format(headerTemplate,paramName,file,contentType);
byte [] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes,0,headerbytes.Length);

FileStream fileStream = new FileStream(file,FileMode.Open,FileAccess.Read);
byte [] buffer = new byte [4096];
int bytesRead = 0;
while((bytesRead = fileStream.Read(buffer,0,buffer.Length))!= 0)
{
rs.Write(buffer,0,bytesRead);
}
fileStream.Close();

byte [] trailer = System.Text.Encoding.ASCII.GetBytes(\r\\\
--+ boundary +--\r\\\
);
rs.Write(trailer,0,trailer.Length);
rs.Close();

//解析响应
WebResponse wresp = null;
尝试
{
wresp = wr.GetResponse();
Stream stream2 = wresp.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
String output = reader2.ReadToEnd();


$ b catch(Exception ex){
Console.Write(Error uploading file+ ex.ToString());
if(wresp!= null)
{
wresp.Close();
wresp = null;
}
}
finally
{
wr = null;


$ / code $ / pre

现在我想跟踪上传的进度。我找到了 C#HttpWebRequest表单发布进度跟踪(用于上传潜在的大文件),但是这个解决方案对我不起作用。 解决方案

您的图像在一个文件中,一次上传4096字节。在每个4096字节之后,你可以调用一些其他的函数来更新一个进度条到新的值。

首先你需要知道文件总数是多少。每当一个包已经上传,你可以计算出百分比,总结所有发送的包,并将它们与要发送的总字节数进行比较。






正如我刚才所链接的线程所看到的那样,在调用GetResponse之前,HttpWebRequest可能不会实际发送数据。



为了防止您尝试使其立即发送数据,通过使用一些解决方法,如设置Content-Length(这意味着您需要知道您预先发送了多少数据),或者可能通过设置传输编码分块(不知道这是否工作,虽然)。你也可以使用一个原始的套接字,所以你有完全的控制。它稍微多一点的工作来发送这样的请求,但不是很复杂。

如果我有一段时间后,你决定去一个原始的套接字,我可以给你一个小例子。


I have the method HttpUploadFile to upload an image with some string parameters:

    public static void HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc)
    {
        Console.Write(string.Format("Uploading {0} to {1}", file, url));
        string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");

        byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
        byte[] omg = boundarybytes;
        HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
        wr.ContentType = "multipart/form-data; boundary=" + boundary;
        wr.Method = "POST";
        wr.KeepAlive = true;
        wr.Credentials = System.Net.CredentialCache.DefaultCredentials;

        Stream rs = wr.GetRequestStream();

        string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
        foreach (string key in nvc.Keys)
        {
            rs.Write(boundarybytes, 0, boundarybytes.Length);
            string formitem = string.Format(formdataTemplate, key, nvc[key]);
            byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);

            rs.Write(formitembytes, 0, formitembytes.Length);
        }
        rs.Write(boundarybytes, 0, boundarybytes.Length);

        string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
        string header = string.Format(headerTemplate, paramName, file, contentType);
        byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
        rs.Write(headerbytes, 0, headerbytes.Length);

        FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
        byte[] buffer = new byte[4096];
        int bytesRead = 0;
        while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
        {
            rs.Write(buffer, 0, bytesRead);
        }
        fileStream.Close();

        byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
        rs.Write(trailer, 0, trailer.Length);
        rs.Close();

        //parsing response
        WebResponse wresp = null;
        try
        {
            wresp = wr.GetResponse();
            Stream stream2 = wresp.GetResponseStream();
            StreamReader reader2 = new StreamReader(stream2);
            String output = reader2.ReadToEnd();


        }
        catch (Exception ex){
            Console.Write("Error uploading file" + ex.ToString());
            if (wresp != null)
            {
                wresp.Close();
                wresp = null;
            }
        }
        finally
        {
            wr = null;
        }
    }

And now I want to track the progress of uploading. I've found C# HttpWebRequest Form Post with Progress Tracking (for uploading potentially large files) but that solution doesn't work for me.

解决方案

You are reading your image out of a file and uploading it 4096 bytes at a time. After each 4096 bytes you could call some other function that updates a progress bar to the new value.

First you will need to know how large the file is, in total. Whenever a package has been uploaded you can calculate the percentage, by summing up all sent packages and comparing them to the total amount of bytes to be sent.


As I just see from the thread you linked, there could be a problem with HttpWebRequest not actually sending the data, before you call GetResponse.

To prevent that you can try to make it send the data right away, by using some workaround like setting the Content-Length (wich means you need to know how much data you are sending beforehand), or possibly by setting the transfer-encoding to chunked (dont know if that works, though). You could also just use a raw socket, so you have total control. Its a little more work to send the request like that, but not very complicated.

If I have some time later on and you decide to go with a raw socket, I could put a small example together for you.

这篇关于上传带有进度跟踪的文件(带参数的HttpWebRequest POST)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆