.NET: il modo più semplice per inviare POST con dati e leggere la risposta


179

Con mia sorpresa, non posso fare nulla di così semplice, da quello che posso dire, nel .NET BCL:

byte[] response = Http.Post
(
    url: "http://dork.com/service",
    contentType: "application/x-www-form-urlencoded",
    contentLength: 32,
    content: "home=Cosby&favorite+flavor=flies"
);

Questo codice ipotetico sopra crea un POST HTTP, con dati, e restituisce la risposta da un Postmetodo su una classe statica Http.

Dato che siamo rimasti senza qualcosa di così semplice, qual è la prossima migliore soluzione?

Come posso inviare un POST HTTP con dati e ottenere il contenuto della risposta?


Questo in realtà ha funzionato perfettamente per me ... stickler.de/it/information/code-snippets/…
Jamie Tabone,

Risposte:


288
   using (WebClient client = new WebClient())
   {

       byte[] response =
       client.UploadValues("http://dork.com/service", new NameValueCollection()
       {
           { "home", "Cosby" },
           { "favorite+flavor", "flies" }
       });

       string result = System.Text.Encoding.UTF8.GetString(response);
   }

Avrai bisogno di questi include:

using System;
using System.Collections.Specialized;
using System.Net;

Se insisti sull'uso di un metodo / classe statici:

public static class Http
{
    public static byte[] Post(string uri, NameValueCollection pairs)
    {
        byte[] response = null;
        using (WebClient client = new WebClient())
        {
            response = client.UploadValues(uri, pairs);
        }
        return response;
    }
}

Quindi semplicemente:

var response = Http.Post("http://dork.com/service", new NameValueCollection() {
    { "home", "Cosby" },
    { "favorite+flavor", "flies" }
});

3
Se si desidera un maggiore controllo sulle intestazioni HTTP, è possibile tentare lo stesso utilizzando HttpWebRequest e riferimento RFC2616 ( w3.org/Protocols/rfc2616/rfc2616.txt ). Le risposte da jball e BFree seguono quel tentativo.
Chris Hutchinson,

9
Questo esempio in realtà non legge la risposta, che era una parte importante della domanda originale!
Jon Watte,

4
Per leggere la risposta, puoi farlo string result = System.Text.Encoding.UTF8.GetString(response). Questa è la domanda in cui ho trovato la risposta.
jporcenaluk,

Questo metodo non funzionerà più se stai cercando di creare un'app di Windows Store per Windows 8.1, poiché WebClient non si trova in System.Net. Invece, usa la risposta di Ramesh e osserva l'uso di "wait".
Stephen Wylie,

2
Ne aggiungerò uno, ma dovresti includere il commento di @jporcenaluk sulla lettura della risposta per migliorare la tua risposta.
Corgalore,

78

Utilizzando HttpClient: per quanto riguarda lo sviluppo di app per Windows 8, mi sono imbattuto in questo.

var client = new HttpClient();

var pairs = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string, string>("pqpUserName", "admin"),
        new KeyValuePair<string, string>("password", "test@123")
    };

var content = new FormUrlEncodedContent(pairs);

var response = client.PostAsync("youruri", content).Result;

if (response.IsSuccessStatusCode)
{


}

6
Funziona anche con un dizionario <String, String>, che lo rende più pulito.
Peter Hedberg,

23
MIGLIORE RISPOSTA MAI .. Oh grazie ai signori, grazie ti amo. Ho lottato .. 2 SETTIMANE FREAKNG .. dovresti vedere tutti i miei post. ARGHH ITS WORKING, YEHAAA <abbracci>
Jimmyt1988

1
Si noti che, quando possibile, non si dovrebbe usare .Resultcon le Asyncchiamate - usare awaitper assicurarsi che il thread dell'interfaccia utente non si blocchi. Inoltre, un semplice new[]funzionerà così come l'elenco; Il dizionario potrebbe ripulire il codice, ma ridurrà alcune funzionalità HTTP.
Matt DeKrey,

1
Oggi (2016) questa è la risposta migliore. HttpClient è più recente di WebClient (la risposta più votata) e presenta alcuni vantaggi: 1) Ha un buon modello di programmazione asincrona su cui Henrik F Nielson è fondamentalmente uno degli inventori di HTTP e ha progettato l'API in modo che è facile seguire lo standard HTTP; 2) È supportato da .Net framework 4.5, quindi ha un certo livello di supporto garantito per il prossimo futuro; 3) Ha anche la versione xcopyable / portable-framework della libreria se vuoi usarla su altre piattaforme - .Net 4.0, Windows Phone ecc ...
Luis Gouveia,

come inviare file con httpclient
Darshan Dave il

47

Usa WebRequest . Da Scott Hanselman :

public static string HttpPost(string URI, string Parameters) 
{
   System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
   req.Proxy = new System.Net.WebProxy(ProxyString, true);
   //Add these, as we're doing a POST
   req.ContentType = "application/x-www-form-urlencoded";
   req.Method = "POST";
   //We need to count how many bytes we're sending. 
   //Post'ed Faked Forms should be name=value&
   byte [] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
   req.ContentLength = bytes.Length;
   System.IO.Stream os = req.GetRequestStream ();
   os.Write (bytes, 0, bytes.Length); //Push it out there
   os.Close ();
   System.Net.WebResponse resp = req.GetResponse();
   if (resp== null) return null;
   System.IO.StreamReader sr = 
         new System.IO.StreamReader(resp.GetResponseStream());
   return sr.ReadToEnd().Trim();
}

32
private void PostForm()
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://dork.com/service");
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    string postData ="home=Cosby&favorite+flavor=flies";
    byte[] bytes = Encoding.UTF8.GetBytes(postData);
    request.ContentLength = bytes.Length;

    Stream requestStream = request.GetRequestStream();
    requestStream.Write(bytes, 0, bytes.Length);

    WebResponse response = request.GetResponse();
    Stream stream = response.GetResponseStream();
    StreamReader reader = new StreamReader(stream);

    var result = reader.ReadToEnd();
    stream.Dispose();
    reader.Dispose();
}

12

Personalmente, penso che l'approccio più semplice per fare un post http e ottenere la risposta sia usare la classe WebClient. Questa classe riassume bene i dettagli. C'è anche un esempio di codice completo nella documentazione MSDN.

http://msdn.microsoft.com/en-us/library/system.net.webclient(VS.80).aspx

Nel tuo caso, vuoi il metodo UploadData (). (Ancora una volta, un esempio di codice è incluso nella documentazione)

http://msdn.microsoft.com/en-us/library/tdbbwh0a(VS.80).aspx

Probabilmente anche UploadString () funzionerà e lo estrarrà di un altro livello.

http://msdn.microsoft.com/en-us/library/system.net.webclient.uploadstring(VS.80).aspx


+1 Sospetto che ci siano molti modi per farlo nel framework.
Jball

7

So che questo è un vecchio thread, ma spero che aiuti qualcuno.

public static void SetRequest(string mXml)
{
    HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://dork.com/service");
    webRequest.Method = "POST";
    webRequest.Headers["SOURCE"] = "WinApp";

    // Decide your encoding here

    //webRequest.ContentType = "application/x-www-form-urlencoded";
    webRequest.ContentType = "text/xml; charset=utf-8";

    // You should setContentLength
    byte[] content = System.Text.Encoding.UTF8.GetBytes(mXml);
    webRequest.ContentLength = content.Length;

    var reqStream = await webRequest.GetRequestStreamAsync();
    reqStream.Write(content, 0, content.Length);

    var res = await httpRequest(webRequest);
}

Che cos'è httpRequest? Mi sta dando un errore "Non esiste".
Rahul Khandelwal il

6

Dato che altre risposte hanno qualche anno, al momento ecco i miei pensieri che potrebbero essere utili:

Il modo più semplice

private async Task<string> PostAsync(Uri uri, HttpContent dataOut)
{
    var client = new HttpClient();
    var response = await client.PostAsync(uri, dataOut);
    return await response.Content.ReadAsStringAsync();
    // For non strings you can use other Content.ReadAs...() method variations
}

Un esempio più pratico

Spesso abbiamo a che fare con tipi noti e JSON, quindi puoi estendere ulteriormente questa idea con un numero qualsiasi di implementazioni, come:

public async Task<T> PostJsonAsync<T>(Uri uri, object dtoOut)
{
    var content = new StringContent(JsonConvert.SerializeObject(dtoOut));
    content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

    var results = await PostAsync(uri, content); // from previous block of code

    return JsonConvert.DeserializeObject<T>(results); // using Newtonsoft.Json
}

Un esempio di come questo potrebbe essere chiamato:

var dataToSendOutToApi = new MyDtoOut();
var uri = new Uri("https://example.com");
var dataFromApi = await PostJsonAsync<MyDtoIn>(uri, dataToSendOutToApi);

5

Puoi usare qualcosa di simile a questo pseudo codice:

request = System.Net.HttpWebRequest.Create(your url)
request.Method = WebRequestMethods.Http.Post

writer = New System.IO.StreamWriter(request.GetRequestStream())
writer.Write("your data")
writer.Close()

response = request.GetResponse()
reader = New System.IO.StreamReader(response.GetResponseStream())
responseText = reader.ReadToEnd
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.