WebClient UploadFileAsync strange behaviour in progress reporting

与世无争的帅哥 提交于 2019-12-30 06:09:00

问题


i need some help with strange WebClient.UploadFileAsync()'s behaviour. I'm uploading a file to a remote HTTP Server (nginx) usind POST Method. The POST is processed trough a PHP script (which Address refers to).

I have this simple code

public void uploadFile(string filePath)
{
    webClient = new WebClient();
    webClient.Credentials = new NetworkCredential(Constant.HTTPUsername,Constant.HTTPPassword);
    webClient.Headers.Add("Test", TestKey);
    webClient.UploadProgressChanged += webClient_UploadProgressChanged;
    webClient.UploadFileCompleted += webClient_UploadFileCompleted;

    try
    {
        webClient.UploadFileAsync(new Uri(Address), "POST", filePath);
    }
    catch (Exception error)
    {
        throw new CustomException(error.Message);
    }
}

And in UploadProgressChanged i simply update a progressBar with the ProgressPercentage given. The first issue is that the Progress percentage reported, with any file size is:

[17.38.14] Progress: 0 Bytes Sent: 175 / 269264
[17.38.14] Progress: 1 Bytes Sent: 8367 / 269264
[17.38.14] Progress: 3 Bytes Sent: 16559 / 269264
[17.38.14] Progress: 4 Bytes Sent: 24751 / 269264
[17.38.14] Progress: 6 Bytes Sent: 32943 / 269264
[17.38.14] Progress: 7 Bytes Sent: 41135 / 269264
[17.38.14] Progress: 9 Bytes Sent: 49327 / 269264
[17.38.14] Progress: 10 Bytes Sent: 57519 / 269264
[17.38.14] Progress: 12 Bytes Sent: 65711 / 269264
[17.38.14] Progress: 13 Bytes Sent: 73903 / 269264
[17.38.14] Progress: 15 Bytes Sent: 82095 / 269264
[17.38.14] Progress: 16 Bytes Sent: 90287 / 269264
[17.38.14] Progress: 18 Bytes Sent: 98479 / 269264
[17.38.15] Progress: 19 Bytes Sent: 106671 / 269264
[17.38.15] Progress: 21 Bytes Sent: 114863 / 269264
[17.38.15] Progress: 22 Bytes Sent: 123055 / 269264
[17.38.15] Progress: 24 Bytes Sent: 131247 / 269264
[17.38.15] Progress: 25 Bytes Sent: 139439 / 269264
[17.38.15] Progress: 27 Bytes Sent: 147631 / 269264
[17.38.16] Progress: 28 Bytes Sent: 155823 / 269264
[17.38.16] Progress: 30 Bytes Sent: 164015 / 269264
[17.38.16] Progress: 31 Bytes Sent: 172207 / 269264
[17.38.16] Progress: 33 Bytes Sent: 180399 / 269264
[17.38.16] Progress: 35 Bytes Sent: 188591 / 269264
[17.38.16] Progress: 36 Bytes Sent: 196783 / 269264
[17.38.17] Progress: 38 Bytes Sent: 204975 / 269264
[17.38.17] Progress: 39 Bytes Sent: 213167 / 269264
[17.38.17] Progress: 41 Bytes Sent: 221359 / 269264
[17.38.17] Progress: 42 Bytes Sent: 229551 / 269264
[17.38.17] Progress: 44 Bytes Sent: 237743 / 269264
[17.38.17] Progress: 45 Bytes Sent: 245935 / 269264
[17.38.17] Progress: 47 Bytes Sent: 254127 / 269264
[17.38.18] Progress: 48 Bytes Sent: 262319 / 269264
[17.38.18] Progress: 49 Bytes Sent: 269220 / 269264
[17.38.18] Progress: 50 Bytes Sent: 269264 / 269264
[17.38.25] Progress: -50 Bytes Sent: 269264 / 269264
[17.38.25] Progress: 100 Bytes Sent: 269264 / 269264
[17.38.25] FileCompleted event raised!

So, searching on the web, i've found that the jump from 50->100, is just a design choice in percentage report..and so i'm fine with it. The strange issue is that even if at 50% (when the entire file was sent), the network interface still generate traffic and is still uploading. In fact, as you can see from the time in the log above, it takes 7 seconds, after file sent, to raise the UploadFileCompletedEvent..in fact, meanwhile, i'm still send the file over HTTP.

The issue here is that i cannot reliably update my UI: the progress bar will grow until 50% but then it will be stuck waiting for upload completition (and this is a bad behaviour since, with large file, this time grows significantly).

The question is: how can i reliably keep the user updated about file upload progress?

Thanks.

P.S. the method works perfectly fine and the file is correctly uploaded to the remote server. The only issue is with the progress reporting.


回答1:


I've just found the issue: it's in the basic HTTP Authentication. For some strange reason, even if i specify Credentials, WebClient submit the first POST request without specifying the credentials in the HTTP Header. After the server replies with a auth-request, it submit the second POST request specifying, correctly, the credentials. In those 2 retryies, my application sends the file 2 times! (That's why i experienced upload activity even after the file was completely sent)

The solution is to force the HTTP basic authentication by manually adding the Authentication header (and deleting the WebClient.Credentials.. line :

string authInfo = userName + ":" + userPassword;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
req.Headers["Authorization"] = "Basic " + authInfo;

This way the 1st (and only) POST request, will be correctly submitted with Authentication header, and the report progress is correctly (just for sharing, i report progress in my progressbar as (e.ProgressPercentage * 2) for the reason above.




回答2:


string authInfo = userName + ":" + userPassword;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
req.Headers["Authorization"] = "Basic " + authInfo;

Place this at the beginning of your post request with e.ProgressPercentage * 2 for your progress reporting purposes.



来源:https://stackoverflow.com/questions/13420983/webclient-uploadfileasync-strange-behaviour-in-progress-reporting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!