.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.