2010-01-21 5 views
6

Vorrei creare le mie richieste HTTP personalizzate. La classe WebClient è molto interessante, ma crea automaticamente le richieste HTTP. Penso che sia necessario creare una connessione di rete al server Web e passare i miei dati su quel flusso, ma non conosco le classi della libreria che supportano questo tipo di cose.Come creare manualmente una richiesta HTTP in .Net?

(Context, sto lavorando su un codice per una classe di programmazione web che sto insegnando. Voglio che i miei studenti a comprendere le basi di quello che sta succedendo dentro la "scatola nera" del HTTP.)

risposta

17

Per capire veramente i meccanismi interni del protocollo HTTP è possibile utilizzare TcpClient classe:

using (var client = new TcpClient("www.google.com", 80)) 
{ 
    using (var stream = client.GetStream()) 
    using (var writer = new StreamWriter(stream)) 
    using (var reader = new StreamReader(stream)) 
    { 
     writer.AutoFlush = true; 
     // Send request headers 
     writer.WriteLine("GET/HTTP/1.1"); 
     writer.WriteLine("Host: www.google.com:80"); 
     writer.WriteLine("Connection: close"); 
     writer.WriteLine(); 
     writer.WriteLine(); 

     // Read the response from server 
     Console.WriteLine(reader.ReadToEnd()); 
    } 
} 

Un'altra possibilità è quella di activate tracing mettendo il seguente nel tuo app.config e usa semplicemente WebClient per eseguire una richiesta HTTP:

<configuration> 
    <system.diagnostics> 
    <sources> 
     <source name="System.Net" tracemode="protocolonly"> 
     <listeners> 
      <add name="System.Net"/> 
     </listeners> 
     </source> 
    </sources> 
    <switches> 
     <add name="System.Net" value="Verbose"/> 
    </switches> 
    <sharedListeners> 
     <add name="System.Net" 
      type="System.Diagnostics.TextWriterTraceListener" 
      initializeData="network.log" /> 
    </sharedListeners> 
    <trace autoflush="true"/> 
    </system.diagnostics> 
</configuration> 

Quindi è possibile eseguire una chiamata HTTP:

using (var client = new WebClient()) 
{ 
    var result = client.DownloadString("http://www.google.com"); 
} 

E infine analizzare il traffico di rete in network.log file generato. WebClient seguirà anche i reindirizzamenti HTTP.

+0

Fantastico esempio, non vedo l'ora di provarlo. Questo è un ottimo modo per visualizzare cosa sta succedendo. Grazie – Jeff

4

Utilizzare le classi WebRequest o WebResponse, come richiesto.

Se è necessario passare a un livello inferiore rispetto a quanto previsto, consultare gli altri System.Net.Sockets. * Classi client come TcpClient.

2

Verificare System.Net.Sockets.TcpClient se si desidera scrivere il proprio client di basso livello. Per HTTP GET e POST è possibile utilizzare le classi HttpWebRequest e HttpWebResponse.

Se sei veramente masochista potresti andare più in basso di TcpClient e implementare il tuo Socket, vedi Socket class.

+0

Yikes. La lunga, lunga strada verso una richiesta web. –

+1

L'utilizzo di TcpClient richiede anche che comprenda il protocollo TELNET su cui è basato Http. –

+1

@John: Ancora un altro bonus! –

2

Nella mia risposta a questo post SO SharePoint 2007, how to check if a folder exists in a document library ho incluso le basi della creazione di HttpWebRequest e della risposta di lettura.

Edit: aggiunto un esempio di codice dal post di cui sopra

System.Net.HttpWebRequest oReq; 
string sUrl = "http://yoursite/sites/somesite/DocumentLibrary"; 
oReq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(sUrl); 

oReq.Method = "GET"; 
oReq.Credentials = System.Net.CredentialCache.DefaultCredentials; 
oReq.AllowAutoRedirect = true; 

//now send the request 
using (System.IO.StreamWriter oRequest = 
     new System.IO.StreamWriter(oReq.GetRequestStream())) { 
    oRequest.WriteLine(); 
} 

//and read all the response 
using (System.Net.HttpWebResponse oResponse = oReq.GetResponse()){ 
    using (System.IO.StreamReader oResponseReader = 
     new System.IO.StreamReader(oResponse.GetResponseStream())){ 
    string sResponse = oResponseReader.ReadToEnd(); 
    } 
} 
+0

-1: blocchi 'using' mancanti per StreamReader/Writer e per la risposta. –

+1

@John Saunders: So che "usare" è un buon modello per la codifica, tuttavia - chiamando close() su un lettore di stream DOES chiude il flusso sottostante e "rilascia qualsiasi risorsa di sistema associata al lettore" (vedi MSDN per la documentazione). Quindi - ti sbagli se pensi che io stia cercando qualcosa qui. – naivists

+0

Si sta verificando una perdita se alcune delle cose tra parentesi generano un'eccezione. – nos

1

Utilizzare WFetch per la dimostrazione.

Per quanto riguarda la programmazione, HttpWebRequest consente di controllare un po 'su richiesta - di nuovo se è per una dimostrazione userei Wireshark ad annusare quello che succede oltre il filo quando si fanno vari compiti con la HttpWebRequest