Могу ли я использовать HttpWebRequest без отключения от сервера? - PullRequest
9 голосов
/ 08 февраля 2011

Я пытаюсь отладить конкретную проблему с моим приложением ASP.NET .Клиент запускает следующий код:

void uploadFile( string serverUrl, string filePath )
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.
        Create( serverUrl );
    CredentialCache cache = new CredentialCache();
    cache.Add( new Uri( serverUrl ), "Basic", new NetworkCredential( "User", "pass" ) );
    request.Credentials = cache;
    request.Method = "POST";
    request.ContentType = "application/octet-stream";
    request.Timeout = 60000;
    request.KeepAlive = true;

    using( BinaryReader reader = new BinaryReader( 
        File.OpenRead( filePath ) ) ) {

        request.ContentLength = reader.BaseStream.Length;
        using( Stream stream = request.GetRequestStream() ) {
            byte[] buffer = new byte[1024];
            while( true ) {
                int bytesRead = reader.Read( buffer, 0, buffer.Length );
                if( bytesRead == 0 ) {
                    break;
                }
                stream.Write( buffer, 0, bytesRead );
            }
        }
    }

     HttpWebResponse result = (HttpWebResponse)request.GetResponse();
     //handle result - not relevant
 }

и Write() выдает исключение с «Не удается записать данные в транспортное соединение: установленное соединение было прервано программным обеспечением на вашем хост-компьютере».текст.Я использовал System.Net tracing и обнаружил, что что-то идет не так, когда я отправляю запрос с установленным Content-Length.

В частности, если я опускаю все, что находится внутри оператора using в кодевыше сервер быстро отвечает WWW-Authenticate, а затем клиент повторно отправляет запрос с WWW-Authenticate, и все идет хорошо, за исключением того, что файл не загружен, и запрос не выполняется намного позже.

Я хотел бы сделатьследующее: отправить запрос без данных, дождаться WWW-Authenticate, затем повторить его с WWW-Authenticate и данными.Поэтому я попытался изменить приведенный выше код: сначала установите все параметры, затем вызовите GetResponse(), затем выполните отправку, но когда я пытаюсь установить свойство ContentLength, возникает исключение с «Это свойство не может быть установлено после начала записи"text.

Так что HttpWebRequest, по-видимому, нельзя использовать повторно.

Как использовать его для повторной отправки запроса без закрытия соединения?

Ответы [ 2 ]

16 голосов
/ 08 февраля 2011

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

Обратите внимание, что вам нужно нужно избавиться от WebResponse, возвращенного request.GetResponse - в противном случае базовая инфраструктура не будет знать, что вы на самом деле с ней покончили, и не сможет повторно использовать соединение.

(Кстати, почему вы используете BinaryReader? Просто используйте поток, возвращаемый File.OpenRead напрямую.)

2 голосов
/ 08 февраля 2011

В дополнение к ответу Джона Скита вам не нужно вручную устанавливать свойство ContentLength. HttpWebRequest автоматически рассчитает и заполнит это свойство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...