2012-11-16 4 views
10

ho bisogno di aiuto con lo strano comportamento di WebClient.UploadFileAsync(). Sto caricando un file su un metodo POST usind remoto HTTP Server (nginx). Il POST viene elaborato tramite uno script PHP (a cui si riferisce l'indirizzo).WebClient UploadFileAsync strano comportamento in corso di segnalazione

ho questo semplice codice

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); 
    } 
} 

E in UploadProgressChanged ho semplicemente aggiornare un ProgressBar con il ProgressPercentage data. Il primo problema è che la percentuale di avanzamento ha riferito, con qualsiasi dimensione del file è:

[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! 

Così, la ricerca sul web, ho trovato che il salto da 50-> 100, è solo una scelta di progettazione in rapporto percentuale .. e quindi sto bene con esso. Il problema strano è che anche se al 50% (quando è stato inviato l'intero file), l'interfaccia di rete genera ancora traffico e continua a caricarsi. In effetti, come puoi vedere dal registro di cui sopra, ci vogliono 7 secondi, dopo il file inviato, per aumentare UploadFileCompletedEvent..in realtà, nel frattempo, sto ancora mandando il file su HTTP.

Il problema qui è che non riesco ad aggiornare in modo affidabile l'interfaccia utente: la barra di avanzamento crescerà fino al 50% ma poi rimarrà bloccata in attesa del completamento del caricamento (e questo è un comportamento errato poiché, con file di grandi dimensioni, questa volta cresce in modo significativo).

La domanda è: come posso tenere aggiornato l'utente in modo affidabile sull'avanzamento del caricamento del file?

Grazie.

P.S. il metodo funziona perfettamente e il file è correttamente caricato sul server remoto. L'unico problema è con la segnalazione dei progressi.

+0

Se tutto va bene, postare la soluzione come risposta e accettarla –

+0

A volte anche postare domande ti aiutano a capirlo :) –

risposta

2

Ho appena trovato il problema: è nell'autenticazione HTTP di base. Per qualche strana ragione, anche se si specifica Credenziali, WebClient invia la prima richiesta POST senza specificare le credenziali nell'intestazione HTTP. Dopo che il server ha risposto con una richiesta di autorizzazione, invia la seconda richiesta POST specificando, correttamente, le credenziali. In questi 2 retryies, la mia applicazione invia il file 2 volte! (Ecco perché ho sperimentato l'attività di upload anche dopo che il file è stato completamente inviato)

La soluzione è quello di forzare l'autenticazione di base HTTP aggiungendo manualmente l'intestazione di autenticazione (e cancellando i WebClient.Credentials .. linea:

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

In questo modo la prima (e unica) richiesta POST, verrà inviata correttamente con l'intestazione di autenticazione e l'avanzamento del report è corretto (solo per la condivisione, riporto l'avanzamento nella mia barra di avanzamento come (e.ProgressPercentage * 2) per il motivo sopra

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

collocare questo, all'inizio della vostra richiesta post con e.ProgressPercentage * 2 per il vostro progresso fini di comunicazione.