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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With