.NET: Einfachste Möglichkeit, POST mit Daten zu senden und Antworten zu lesen

179

Zu meiner Überraschung kann ich in der .NET BCL nichts annähernd so Einfaches tun, wie ich sagen kann:

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

Dieser obige hypothetische Code erstellt einen HTTP-POST mit Daten und gibt die Antwort einer PostMethode für eine statische Klasse zurück Http.

Was ist die nächstbeste Lösung, da wir auf etwas so Einfaches verzichten müssen?

Wie sende ich einen HTTP-POST mit Daten UND erhalte den Inhalt der Antwort?

AgileMeansDoAsLittleAsPossible
quelle
Das hat tatsächlich perfekt für mich funktioniert ... stickler.de/de/information/code-snippets/…
Jamie Tabone

Antworten:

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

Sie benötigen Folgendes:

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

Wenn Sie darauf bestehen, eine statische Methode / Klasse zu verwenden:

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

Dann einfach:

var response = Http.Post("http://dork.com/service", new NameValueCollection() {
    { "home", "Cosby" },
    { "favorite+flavor", "flies" }
});
Chris Hutchinson
quelle
3
Wenn Sie mehr Kontrolle über die HTTP-Header wünschen, können Sie dies auch mit HttpWebRequest und der Referenz RFC2616 ( w3.org/Protocols/rfc2616/rfc2616.txt ) versuchen . Antworten von jball und BFree folgen diesem Versuch.
Chris Hutchinson
9
In diesem Beispiel wird die Antwort nicht gelesen, was ein wichtiger Teil der ursprünglichen Frage war!
Jon Watte
4
Um die Antwort zu lesen, können Sie dies tun string result = System.Text.Encoding.UTF8.GetString(response). Dies ist die Frage, auf die ich die Antwort gefunden habe.
Jporcenaluk
Diese Methode funktioniert nicht mehr, wenn Sie versuchen, eine Windows Store-App für Windows 8.1 zu erstellen, da WebClient in System.Net nicht gefunden wird. Verwenden Sie stattdessen Rameshs Antwort und untersuchen Sie die Verwendung von "Warten".
Stephen Wylie
2
Ich werde dies plus eins hinzufügen, aber Sie sollten einen @ jporcenaluk-Kommentar zum Lesen der Antwort einfügen, um Ihre Antwort zu verbessern.
Corgalore
78

Verwenden von HttpClient: Bei der Entwicklung von Windows 8-Apps bin ich darauf gestoßen.

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)
{


}
Ramesh
quelle
6
Funktioniert auch mit einem Wörterbuch <String, String>, wodurch es sauberer wird.
Peter Hedberg
22
Beste Antwort aller Zeiten. Oh, danke den Herren, danke, ich liebe dich. Ich habe gekämpft .. 2 FREAKNG WOCHEN .. Sie sollten alle meine Beiträge sehen. ARGHH SEINE ARBEIT, YEHAAA <umarmt>
Jimmyt1988
1
Beachten Sie, dass Sie, wenn möglich, nicht .Resultmit AsyncAufrufen verwenden sollten - verwenden awaitSie diese Option, um sicherzustellen, dass Ihr UI-Thread nicht blockiert. Auch eine einfache new[]wird genauso funktionieren wie die Liste; Dictionary bereinigt möglicherweise den Code, reduziert jedoch einige HTTP-Funktionen.
Matt DeKrey
1
Heutzutage (2016) ist dies die beste Antwort. HttpClient ist neuer als WebClient (die am häufigsten gewählte Antwort) und hat einige Vorteile: 1) Es hat ein gutes asynchrones Programmiermodell, an dem Henrik F. Nielson arbeitet, der im Grunde einer der Erfinder von HTTP ist, und er hat die API so entworfen Es fällt Ihnen leicht, dem HTTP-Standard zu folgen. 2) Es wird vom .Net-Framework 4.5 unterstützt, sodass es auf absehbare Zeit ein gewisses Maß an Unterstützung bietet. 3) Es hat auch die xcopyable / portable-Framework-Version der Bibliothek, wenn Sie es auf anderen Plattformen verwenden möchten - .Net 4.0, Windows Phone usw.
Luis Gouveia
wie man Dateien mit httpclient sendet
Darshan Dave
47

Verwenden Sie WebRequest . Von 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();
}
jball
quelle
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();
}
BKostenlos
quelle
12

Persönlich denke ich, dass der einfachste Ansatz, einen http-Beitrag zu erstellen und die Antwort zu erhalten, die Verwendung der WebClient-Klasse ist. Diese Klasse abstrahiert die Details. Es gibt sogar ein vollständiges Codebeispiel in der MSDN-Dokumentation.

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

In Ihrem Fall möchten Sie die UploadData () -Methode. (Auch hier ist ein Codebeispiel in der Dokumentation enthalten.)

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

UploadString () wird wahrscheinlich auch funktionieren und es wird eine weitere Ebene abstrahiert.

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

David
quelle
+1 Ich vermute, es gibt eine Reihe von Möglichkeiten, dies im Framework zu tun.
Jball
7

Ich weiß, dass dies ein alter Thread ist, aber ich hoffe, er hilft jemandem.

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);
}
Murali
quelle
Was ist httpRequest? Es gibt mir einen Fehler "Existiert nicht".
Rahul Khandelwal
6

Angesichts der Tatsache, dass andere Antworten einige Jahre alt sind, sind hier meine Gedanken, die hilfreich sein können:

Einfachster Weg

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
}

Ein praktischeres Beispiel

Oft haben wir es mit bekannten Typen und JSON zu tun, sodass Sie diese Idee mit einer beliebigen Anzahl von Implementierungen weiter ausbauen können, z.

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
}

Ein Beispiel, wie dies genannt werden könnte:

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

Sie können so etwas wie diesen Pseudocode verwenden:

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
Paludarium
quelle