2 votes

Utiliser WebClient, la méthode DownloadData et l'en-tête personnalisé pour poster sur une page web

** Mise à jour J'ai une solution ci-dessous, mais elle est plutôt manuelle... s'il y a un moyen plus facile, je préférerais qu'on me réponde.

Je veux enregistrer le temps d'exécution et de téléchargement d'une page web, et j'essaie d'utiliser la méthode WebClient.DownloadDataAsync pour envoyer des données à une page et obtenir un résultat.

Je sais qu'il existe de nombreuses façons d'envoyer des messages en utilisant des objets WebClient ou WebRequest, mais aucune d'entre elles n'envoie l'événement DownloadProgressChanged. Cet événement est essentiel, car je veux suivre la progression du téléchargement, qui est de l'ordre de plus de 30 mégaoctets.

Je pense que la meilleure façon de procéder serait de construire l'en-tête manuellement, mais je me trouve dans une impasse. Principalement, je ne peux pas ajouter les données à la requête.

WebClient client = new WebClient();
//!!!!*****no idea how to add the following data to the request
string data = "test1=value"; 
client.Headers.Add( "POST", "/About.aspx HTTP/1.1" );
client.Headers.Add( "Host", "http://localhost:12065" );
client.Headers.Add( "Content-Type", "application/x-www-form-urlencoded" );
client.Headers.Add( "Content-length", data.Length.ToString() );

client.DownloadProgressChanged += OnDownloadProgressChanged;
client.DownloadDataCompleted += OnDownloadDataCompleted;
client.DownloadDataAsync( new Uri( "http://localhost:12065/About.aspx" ) );

Je suis ouvert à d'autres solutions, ou à la possibilité de faire fonctionner l'en-tête dans cet exemple comme si le client envoyait un POST.

4voto

Nicholas Points 805

OK... j'ai trouvé un moyen de le faire en utilisant WebRequest. C'est un peu plus compliqué, mais ça marche. Je suis surpris que WebClient ne fasse pas déjà cela, mais il semble que WebClient ait un certain nombre de problèmes inattendus.

//Using System.Diagnostics, set up a Stopwatch to time the execution
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();

//convert your post data into a byte array... we're dealing with streams here
byte[] postData = Encoding.ASCII.GetBytes( postData );

//We're using the WebRequest object found in System.Net to do our work for us
WebRequest request = WebRequest.Create( url );

//Set all your headers
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.ContentLength = postData.Length;

//set up your request stream and write out your post data
Stream stream = request.GetRequestStream();
stream.Write( postData, 0, postData.Length );
stream.Close();

//Send the data and wait for a response. [blocking operation]
WebResponse response = request.GetResponse();

//Once you reach this line, the server has finished doing it's work, 
//and downloading has commenced
Console.WriteLine( "First Response: {0}", stopWatch.Elapsed );

//Start timing the download, wouldn't it be nice is there was a restart method? (.Net 4.0)
stopWatch.Reset();
stopWatch.Start();

//We want to receive the data. so ask for the response stream
Stream reponseStream = response.GetResponseStream();

//In my case, there are megabytes of information, so the console is no good,
//I'll store it in a file.
FileStream fileStream = File.Open( "result.txt", FileMode.OpenOrCreate );

//create a buffer to collect data as it is downloaded
byte[] buffer = new byte[1024];

//This loop will run as long as the responseStream can read data. (i.e. downloading data)
//Once it reads 0... the downloading has completed
int resultLength;
while( ( resultLength = reponseStream.Read( buffer, 0, buffer.Length ) ) != 0 )
{
    //You could further measure progress here... but I don't care.
    fileStream.Write( buffer, 0, resultLength );
}

//Everything is done... how long did it take to download?
Console.WriteLine( "Download Complete: {0}", stopWatch.Elapsed );

//housekeeping
fileStream.Flush();
fileStream.Close();
stopWatch.Stop();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X