Ошибка .NET при вызове System.Net.WebClient.UploadFileAsync - PullRequest
6 голосов
/ 14 июня 2011

Я работаю с классом System.Net.WebClient и пытаюсь загрузить файл с помощью метода UploadFileAsync.Я использую Visual Studio 2010, и все мои проекты настроены на использование стандартной среды выполнения .NET 4.0, а не клиентской библиотеки.

Ниже приведен небольшой раздел кода, который я использую.Примерно в 90% случаев я получаю следующую ошибку:

Невозможно привести объект типа 'System.ComponentModel.AsyncOperation' к типу '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()

FTP-серверы, на которые я пытаюсь загрузить данные, являются внутренними для моей организации, но на одном запущен IPSwitches WS-FTP, а на другом - FTP-сайт IIS 6.0, и у меня возникла та же проблема с обоими серверами.

Я искал все выше и ниже других с похожей проблемой, но безрезультатно.

Фактическая строка, на которой происходит исключение, - это вызов метода _Client.UploadFileAsync.

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
}

1 Ответ

4 голосов
/ 15 июня 2011

Это довольно интересно. Если посмотреть на справочный источник (WebClient.cs), в первой строке UploadFileAsyncWriteCallback параметр state преобразуется в UploadBitsState.

В методе UploadFileAsync есть код обработки исключений, который гласит:

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 относится к типу AsyncOperation.

Похоже, что вызов UploadFileAsyncWriteCallback здесь является ошибкой, потому что он передает объект неправильного типа в обратный вызов. Обратный вызов выполняет приведение в стиле C (т.е. UploadBitsState uploadState = (UploadBitsState)state;).

Но это произойдет, только если что-то вызовет исключение во время загрузки.

Возможно ли, что что-то в ваших обработчиках событий ProgressChanged или UploadCompleted вызывает исключение? Либо тот, либо один из параметров, которые вы передаете UploadFileAsync, недопустим.

Подробнее

Похоже, в UploadFileAsync есть ошибка. Например, следующий бросок InvalidCastException, когда согласно документации он должен бросить 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);

Я сообщил об ошибке на https://connect.microsoft.com/VisualStudio/feedback/details/675575/webclient-uploadfileasync-throws-invalidcastexception

Однако, судя по всему, я бы сказал, что причина, по которой выдается исключение, кроется в вашем коде. К сожалению, невозможно сказать , где , потому что UploadFileAsync теряет информацию об исключении. Возможно, как заметил кто-то другой, попытка синхронной загрузки позволит пролить больше света на эту тему.

...