2011-02-08 15 views
9

Estoy tratando de depurar a specific issue with my ASP.NET application. El cliente se ejecuta el siguiente código:¿Puedo reutilizar HttpWebRequest sin desconectarme del servidor?

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 
} 

y Write() tiros con una excepción "No se puede escribir datos en la conexión de transporte: una conexión establecida fue abortado por el software en su ordenador central." texto. Usé System.Net tracing y descubrí que algo va mal cuando envío la solicitud con el Content-Length conjunto.

concreto, si omito todo lo que está dentro using comunicado en el código anterior el servidor responde con prontitud con WWW-Authenticate y luego el cliente reposts la solicitud con WWW-Authenticate y todo va bien, excepto el archivo en no ha subido y la solicitud no mucho más tarde.

Me gustaría hacer lo siguiente: enviar una solicitud sin datos, esperar a WWW-Authenticate, luego repetirlo con WWW-Authenticate y los datos. Así que traté de modificar el código anterior: primero configuré todos los parámetros, luego llamé al GetResponse(), luego realicé el envío, pero cuando intento establecer la propiedad ContentLength, se lanza una excepción con el texto "Esta propiedad no puede establecerse después de que el texto haya comenzado".

Así que HttpWebRequest parece ser no reutilizable.

¿Cómo lo vuelvo a utilizar para volver a enviar la solicitud sin cerrar la conexión?

+0

También tengo el mismo problema. Si obtuvo la solución, proporcione o muestre el nuevo código modificado que me ayudará. – Herin

+0

@Herin: no hay solución si usa autenticación con nonce. Si usa algo así como la autenticación básica, puede simplemente configurar los encabezados de "Autorización" para que no haya una fase 'WWW-Authenticate'. – sharptooth

+0

Pero si recibo un error en la línea 'stream.Write (buffer, 0, bytesRead)' entonces, ¿cuál es la solución para eso? ¿Puedes proporcionar tu código modificado para que pueda entender mejor? Gracias – Herin

Respuesta

16

No reutiliza una solicitud, como su nombre indica, es una solicitud. Sin embargo, si emite varias solicitudes para el mismo host, .NET reutilizará la conexión de red subyacente de manera predeterminada.

Tenga en cuenta que hace necesidad de disponer de la WebResponse devuelto por request.GetResponse - de lo contrario la infraestructura subyacente no sabrá que en realidad estás terminado con él, y no será capaz de volver a utilizar la conexión.

(Dicho sea de paso, ¿por qué está usando BinaryReader? Sólo tiene que utilizar la corriente devuelta por File.OpenRead directamente.)

+0

Puedo responder por la eliminación de WebResponse. No me deshice de WebResponse en una de mis aplicaciones y generó una desagradable pérdida de memoria porque estaba creando instancias de HttpWebRequests. – jlafay

+0

Justo, pero ¿qué otro mecanismo podría usar para resolver mi problema, específicamente que necesito autenticarme y luego volver a usar el mismo 'WWW-Authenticate'? – sharptooth

+0

@sharptooth: No está claro por qué no puedes simplemente tomar el encabezado de la respuesta y usarlo en la próxima solicitud. ¿Por qué crees que tienes que reutilizar el mismo objeto? –

2

Además de la respuesta de la Jon Skeet, que no es necesario establecer manualmente la propiedad ContentLength. HttpWebRequest calculará automáticamente y poblará esa propiedad.

Cuestiones relacionadas