2012-03-30 16 views
24

Estoy desarrollando una página web que necesita tomar una solicitud de publicación HTTP y leerla en una matriz de bytes para su posterior procesamiento. Estoy algo atrapado en cómo hacer esto, y estoy perplejo sobre cuál es la mejor manera de lograrlo. Aquí está mi código hasta ahora:Leer solicitud Http en matriz de bytes

public override void ProcessRequest(HttpContext curContext) 
    { 
     if (curContext != null) 
     { 
      int totalBytes = curContext.Request.TotalBytes; 
      string encoding = curContext.Request.ContentEncoding.ToString(); 
      int reqLength = curContext.Request.ContentLength; 
      long inputLength = curContext.Request.InputStream.Length; 
      Stream str = curContext.Request.InputStream; 

     } 
     } 

Estoy comprobando la longitud de la solicitud y su número total de bytes que es igual a 128. Ahora lo hacen sólo hay que utilizar un objeto Stream para conseguirlo en formato de byte []? ¿Voy en la dirección correcta? No estoy seguro de como proceder. Cualquier consejo sería genial. Necesito obtener la solicitud HTTP completa en el campo byte [].

Gracias!

Respuesta

50

La manera más simple es copiarlo en un MemoryStream - luego llame al ToArray si es necesario.

Si está utilizando .NET 4, eso es muy fácil:

MemoryStream ms = new MemoryStream(); 
curContext.Request.InputStream.CopyTo(ms); 
// If you need it... 
byte[] data = ms.ToArray(); 

EDIT: Si usted no está utilizando .NET 4, puede crear su propia implementación de CopyTo. Aquí hay una versión que actúa como un método de extensión:

public static void CopyTo(this Stream source, Stream destination) 
{ 
    // TODO: Argument validation 
    byte[] buffer = new byte[16384]; // For example... 
    int bytesRead; 
    while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     destination.Write(buffer, 0, bytesRead); 
    } 
} 
+0

No tengo el .CopyTo? – Encryption

+0

¿Cómo usaría el flujo de memoria sin la opción .CopyTo? – Encryption

+0

@Encryption: Puede implementar algo muy similar usted mismo - Lo editaré en un minuto ... –

0
class WebFetch 
{ 
static void Main(string[] args) 
{ 
    // used to build entire input 
    StringBuilder sb = new StringBuilder(); 

    // used on each read operation 
    byte[] buf = new byte[8192]; 

    // prepare the web page we will be asking for 
    HttpWebRequest request = (HttpWebRequest) 
     WebRequest.Create(@"http://www.google.com/search?q=google"); 

    // execute the request 
    HttpWebResponse response = (HttpWebResponse) 
     request.GetResponse(); 

    // we will read data via the response stream 
    Stream resStream = response.GetResponseStream(); 

    string tempString = null; 
    int count = 0; 

    do 
    { 
     // fill the buffer with data 
     count = resStream.Read(buf, 0, buf.Length); 

     // make sure we read some data 
     if (count != 0) 
     { 
      // translate from bytes to ASCII text 
      tempString = Encoding.ASCII.GetString(buf, 0, count); 

      // continue building the string 
      sb.Append(tempString); 
     } 
    } 
    while (count > 0); // any more data to read? 

    // print out page source 
    Console.WriteLine(sb.ToString()); 
    Console.Read(); 
    } 
} 
+0

Buen código, pero supone que los datos que se obtienen son datos de cadena. Si fuera un archivo u otra cosa que debe guardarse como bytes, esta no sería la forma de hacerlo. Sin embargo, no voy a votar ni a favor ni en contra. – vapcguy

12

sólo puede utilizar WebClient para que ...

WebClient c = new WebClient(); 
byte [] responseData = c.DownloadData(..) 

Dónde .. es la dirección URL de los datos.

+0

Tenga en cuenta que 'DownloadData' nunca lanzará excepciones para 4xx y 5xx – Nathan

0

que tienen una función que lo hace, con el envío de la secuencia de respuesta:

private byte[] ReadFully(Stream input) 
{ 
    try 
    { 
     int bytesBuffer = 1024; 
     byte[] buffer = new byte[bytesBuffer]; 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      int readBytes; 
      while ((readBytes = input.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       ms.Write(buffer, 0, readBytes); 
      } 
      return ms.ToArray(); 
     } 
    } 
    catch (Exception ex) 
    { 
     // Exception handling here: Response.Write("Ex.: " + ex.Message); 
    } 
} 

Puesto que usted tiene Stream str = curContext.Request.InputStream;, usted podría simplemente hacer:

byte[] bytes = ReadFully(str); 

Si se hubiera hecho esto:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(someUri); 
req.Credentials = CredentialCache.DefaultCredentials; 
HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); 

se podría llamar de esta manera:

byte[] bytes = ReadFully(resp.GetResponseStream());