2012-03-30 18 views
24

Zajmuję się tworzeniem strony internetowej, która musi pobrać żądanie HTTP Post i odczytać ją do tablicy bajtów w celu dalszego przetwarzania. Trochę utknąłem na tym, jak to zrobić i jestem zaskoczony, jaki jest najlepszy sposób na osiągnięcie tego. Oto mój kod do tej pory:Odczytaj żądanie HTTP do tablicy bajtów

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; 

     } 
     } 

mam sprawdzanie długości wniosku i jego całkowitych bajtów, która jest równa 128. Teraz mogę po prostu trzeba użyć obiektu Stream, aby ją do byte [] formacie? Czy zmierzam w dobrym kierunku? Nie wiem, jak postępować. Każda rada byłaby świetna. Potrzebuję pobrać całe żądanie HTTP do pola bajtu [].

Dzięki!

Odpowiedz

50

Najprostszym sposobem jest skopiowanie go do numeru MemoryStream - następnie wywołanie ToArray, jeśli jest to konieczne.

Jeśli używasz .NET 4, to jest bardzo proste:

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

EDIT: Jeśli nie używasz .NET 4, można stworzyć własną implementację copyTo. Oto wersja, która działa jako metodę rozszerzenia:

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

Nie mam .CopyTo? – Encryption

+0

Jak używać strumienia pamięci bez opcji .CopyTo? – Encryption

+0

@Encryption: Możesz zaimplementować coś bardzo podobnego samemu - będę edytować go za chwilę ... –

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

Dobry kod, ale zakłada, że ​​pobierane dane są danymi ciągu. Jeśli był to plik lub coś innego, co musiało być przechowywane jako bajty, nie byłby to sposób na zrobienie tego. Nie będę jednak głosował ani nie głosował w tej sprawie. – vapcguy

12

można po prostu użyć WebClient do tego ...

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

Gdzie .. jest adres URL dla danych.

+0

Należy pamiętać, że 'DownloadData' nigdy nie wyśle ​​wyjątków dla 4xx i 5xx – Nathan

0

Mam funkcję, która robi, wysyłając w strumieniu odpowiedzi:

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); 
    } 
} 

Skoro masz Stream str = curContext.Request.InputStream;, można następnie po prostu zrobić:

byte[] bytes = ReadFully(str); 

Jeśli to zrobił:

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

nazwałbyś to w ten sposób:

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