6 votes

Erreur .NET lors de l'appel de System.Net.WebClient.UploadFileAsync

Je travaille avec le System.Net.WebClient et je tente de télécharger un fichier à l'aide de la méthode UploadFileAsync. J'utilise Visual Studio 2010, et tous mes projets sont configurés pour utiliser le runtime standard .NET 4.0, et non la bibliothèque client.

Vous trouverez ci-dessous une petite partie du code que j'utilise. Environ 90 % du temps, j'obtiens l'erreur suivante :

Impossible de convertir l'objet de type 'System.ComponentModel.AsyncOperation' en type 'UploadBitsState'.

Stack Trace:
 at System.Net.WebClient.UploadFileAsyncWriteCallback(Byte[] returnBytes, Exception exception, Object state)
 at System.Net.WebClient.UploadFileAsync(Uri address, String method, String fileName,   Object userToken)
 at FileUpload._StartUpload()

Les serveurs FTP vers lesquels je tente de télécharger sont internes à mon organisation, mais l'un d'entre eux utilise IPSwitches WS-FTP et l'autre un site FTP IIS 6.0. J'ai rencontré le même problème avec les deux serveurs.

J'ai cherché partout d'autres personnes ayant un problème similaire, mais en vain.

La ligne sur laquelle l'exception se produit est la suivante _Client.UploadFileAsync l'appel de la méthode.

private void _StartUpload()
{
    try
    {
        _Client = new WebClient
        {
            Credentials = _Credentials
        };
        _Client.UploadProgressChanged += ProgressChanged;
        _Client.UploadFileCompleted += UploadCompleted;
        _Client.UploadFileAsync(FileBeingUploaded, "STOR", _LocalFile, null);
    }
    catch (Exception exception)
    {
        // Methods calls removed for brevity
    }
}

private void UploadCompleted(Object sender, UploadFileCompletedEventArgs e)
{
    // Methods calls removed for brevity
}

private void ProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
    // Methods calls removed for brevity
}

4voto

Jim Mischel Points 68586

C'est assez intéressant. En regardant la source de référence (WebClient.cs), la première ligne du fichier UploadFileAsyncWriteCallback lance le state pour UploadBitsState .

Dans la méthode UploadFileAsync il y a un code de gestion des exceptions qui lit :

catch (Exception e)
{
    if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException)
    { 
        throw; 
    }
    if(fs != null){ 
        fs.Close();
    }
    if (!(e is WebException || e is SecurityException)) {
        e = new WebException(SR.GetString(SR.net_webclient), e); 
    }
    UploadFileAsyncWriteCallback(null, e, asyncOp); 
}

asyncOp est de type AsyncOperation .

Il semble que l'appel à UploadFileAsyncWriteCallback Il s'agit d'un bogue, car il transmet un objet de type incorrect à la fonction de rappel. Le callback fait un cast de style C (i.e. UploadBitsState uploadState = (UploadBitsState)state; ).

Mais cela ne se produira que si quelque chose déclenche une exception pendant le téléchargement.

Est-il possible que quelque chose dans votre ProgressChanged o UploadCompleted Les gestionnaires d'événements lancent une exception ? Soit cela, soit l'un des paramètres que vous passez à la fonction UploadFileAsync est invalide.

Plus d'informations

On dirait vraiment qu'il y a un bug dans UploadFileAsync . Par exemple, les lancers suivants InvalidCastException alors que selon la documentation, il devrait lancer WebException .

var targetUri = new Uri("ftp://example.com/file.txt");
var srcFile = string.Empty;  // documentation says this will throw WebException
var client = new WebClient();
client.UploadFileAsync(targetUri, "STOR", srcFile, null);

J'ai signalé le bogue à https://connect.microsoft.com/VisualStudio/feedback/details/675575/webclient-uploadfileasync-throws-invalidcastexception

Cependant, à première vue, je dirais que la raison pour laquelle une exception est levée se trouve dans votre code. Malheureusement, il est impossible de dire parce que UploadFileAsync perd l'information sur les exceptions. Peut-être que, comme quelqu'un d'autre l'a fait remarquer, essayer un téléchargement synchrone apportera plus de lumière sur le sujet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X