Cara memposting data ke URL tertentu menggunakan WebClient di C #

319

Saya perlu menggunakan "HTTP Post" dengan WebClient untuk mengirim beberapa data ke URL spesifik yang saya miliki.

Sekarang, saya tahu ini bisa diselesaikan dengan WebRequest tetapi untuk beberapa alasan saya ingin menggunakan WebClient sebagai gantinya. Apakah itu mungkin? Jika demikian, dapatkah seseorang menunjukkan kepada saya contoh atau mengarahkan saya ke arah yang benar?

SolidSnake
sumber

Jawaban:

374

Saya baru saja menemukan solusinya dan ya itu lebih mudah dari yang saya kira :)

jadi inilah solusinya:

string URI = "http://www.myurl.com/post.php";
string myParameters = "param1=value1&param2=value2&param3=value3";

using (WebClient wc = new WebClient())
{
    wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
    string HtmlResult = wc.UploadString(URI, myParameters);
}

itu bekerja seperti pesona :)

SolidSnake
sumber
28
A nitpick: lebih baik menggunakan HttpRequestHeader.ContentTypeanggota enumerasi di sini seperti ini web.Headers[HttpRequestHeader.ContentType]: p
Alex
12
Nitpick lain, Anda harus membuang webclient dengan benar menggunakan .dispose atau idiom "using": using (WebClient wc = new WebClient ()) {// kode Anda di sini}
Mikey Hogarth
1
@RobinVanPersi Saya pikir ShikataGanai (Rafik bari) berarti bahwa jawaban lain ( stackoverflow.com/a/13061805/1160796 ) lebih baik karena menangani pengkodean untuk Anda.
basher
3
@ alpsystems.com Objek IDisposable harus dibuang dengan benar oleh programmer, baik dengan membungkus menggunakan atau dengan secara eksplisit menggunakan .Dispose (). Pengumpul sampah tidak dapat melacak sumber daya yang tidak dikelola, seperti penangan file, koneksi basis data dan sebagainya
ccalboni
1
Untuk memperluas penjelasan @ ccalboni. Dalam beberapa kasus pengumpul sampah akan membersihkan sumber daya unmanaged dan sejenisnya dengan memanggil destructor (misalnya, WebClientmewarisi dari Component, yang berisi ~Component() {Dispose(false);}). Masalahnya adalah bahwa pemulung dapat mengambil waktu lama secara sewenang-wenang untuk melakukannya, karena itu tidak memperhitungkan sumber daya yang tidak dikelola ketika membuat keputusan pengumpulan. Sumber daya bernilai tinggi harus dibersihkan sesegera mungkin. Misalnya, membiarkan buka suatu pegangan file yang tidak dibutuhkan dapat memblokir file agar tidak dihapus atau ditulis oleh kode lain.
Brian
362

Ada metode bawaan yang disebut UploadValues yang dapat mengirim HTTP POST (atau segala jenis metode HTTP) DAN menangani konstruksi badan permintaan (menyatukan parameter dengan "&" dan melepaskan karakter dengan pengkodean url) dalam format data formulir yang tepat:

using(WebClient client = new WebClient())
{
    var reqparm = new System.Collections.Specialized.NameValueCollection();
    reqparm.Add("param1", "<any> kinds & of = ? strings");
    reqparm.Add("param2", "escaping is already handled");
    byte[] responsebytes = client.UploadValues("http://localhost", "POST", reqparm);
    string responsebody = Encoding.UTF8.GetString(responsebytes);
}
Endy Tjahjono
sumber
1
Bagaimana jika saya ingin memposting model ke controller? Masih bisakah saya menggunakan reqparm.Add (string, string)?
Burak Karakuş
6
@ BurakKarakuş maksud Anda ingin mengirim JSON di badan? Maka Anda mungkin ingin menggunakan WebClient.UploadString . Jangan lupa untuk menambahkan Content-Type: application / json di header.
Endy Tjahjono
@EndyTjahjono: Bagaimana saya bisa memposting nilai tombol radio. Asumsikan saya memiliki 3 tombol radio milik grup yang sama.
Asad Refai
Bagaimana saya mendapatkan kode respons? Header respons? Apakah saya harus menguraikan respons? Apakah ada cara mudah untuk melakukan itu?
Jay Sullivan
PERINGATAN . namevalueCollection donest mengizinkan kunci yang sama. ini dapat menyebabkan begaiviour aneh
bh_earth0
40

Menggunakan WebClient.UploadStringatau WebClient.UploadDataAnda dapat POST data ke server dengan mudah. Saya akan menunjukkan contoh menggunakan UploadData, karena UploadString digunakan dengan cara yang sama seperti DownloadString.

byte[] bret = client.UploadData("http://www.website.com/post.php", "POST",
                System.Text.Encoding.ASCII.GetBytes("field1=value1&amp;field2=value2") );

            string sret = System.Text.Encoding.ASCII.GetString(bret);

lebih lanjut: http://www.daveamenta.com/2008-05/c-webclient-usage/

Pranay Rana
sumber
5
lebih baik digunakan: client.Encoding = System.Text.UTF8Encoding.UTF8; string varValue = Uri.EscapeDataString (nilai);
Yuriy Vikulov
23
string URI = "site.com/mail.php";
using (WebClient client = new WebClient())
{
    System.Collections.Specialized.NameValueCollection postData = 
        new System.Collections.Specialized.NameValueCollection()
       {
              { "to", emailTo },  
              { "subject", currentSubject },
              { "body", currentBody }
       };
    string pagesource = Encoding.UTF8.GetString(client.UploadValues(URI, postData));
}
Andrew
sumber
21
//Making a POST request using WebClient.
Function()
{    
  WebClient wc = new WebClient();

  var URI = new Uri("http://your_uri_goes_here");

  //If any encoding is needed.
  wc.Headers["Content-Type"] = "application/x-www-form-urlencoded";
  //Or any other encoding type.

  //If any key needed

  wc.Headers["KEY"] = "Your_Key_Goes_Here";

  wc.UploadStringCompleted += 
      new UploadStringCompletedEventHandler(wc_UploadStringCompleted);

  wc.UploadStringAsync(URI,"POST","Data_To_Be_sent");    
}

void wc__UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)    
{  
  try            
  {          
     MessageBox.Show(e.Result); 
     //e.result fetches you the response against your POST request.         
  }
  catch(Exception exc)         
  {             
     MessageBox.Show(exc.ToString());            
  }
}
TeJ
sumber
Menggunakan versi async yang baik semua di atas memposting dan memblokir eksekusi.
Juan
hapus double __ untuk memperbaiki wc__UploadStringCompleted
Joel Davis
1
Semua jawaban di atas akan bekerja dengan baik dalam pengujian, tetapi dalam situasi kehidupan nyata dengan internet yang buruk ini adalah jawaban yang lebih baik.
Joel Davis
2

Menggunakan sederhana client.UploadString(adress, content);biasanya berfungsi dengan baik tetapi saya pikir harus diingat bahwa WebExceptionakan dilemparkan jika tidak kode status HTTP berhasil dikembalikan. Saya biasanya menanganinya seperti ini untuk mencetak pesan pengecualian yang dikembalikan oleh server jauh:

try
{
    postResult = client.UploadString(address, content);
}
catch (WebException ex)
{
    String responseFromServer = ex.Message.ToString() + " ";
    if (ex.Response != null)
    {
        using (WebResponse response = ex.Response)
        {
            Stream dataRs = response.GetResponseStream();
            using (StreamReader reader = new StreamReader(dataRs))
            {
                responseFromServer += reader.ReadToEnd();
                _log.Error("Server Response: " + responseFromServer);
            }
        }
    }
    throw;
}
Ogglas
sumber
terima kasih, Ogglas. Saya menghabiskan banyak waktu untuk menemukan kesalahan dan kode Anda memberi saya lebih banyak informasi untuk memperbaikinya.
Kate
1

Menggunakan webapiclient dengan model mengirim permintaan parameter json serialize.

PostModel.cs

    public string Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public int Age { get; set; }

WebApiClient.cs

internal class WebApiClient  : IDisposable
  {

    private bool _isDispose;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public void Dispose(bool disposing)
    {
        if (!_isDispose)
        {

            if (disposing)
            {

            }
        }

        _isDispose = true;
    }

    private void SetHeaderParameters(WebClient client)
    {
        client.Headers.Clear();
        client.Headers.Add("Content-Type", "application/json");
        client.Encoding = Encoding.UTF8;
    }

    public async Task<T> PostJsonWithModelAsync<T>(string address, string data,)
    {
        using (var client = new WebClient())
        {
            SetHeaderParameters(client);
            string result = await client.UploadStringTaskAsync(address, data); //  method:
    //The HTTP method used to send the file to the resource. If null, the default is  POST 
            return JsonConvert.DeserializeObject<T>(result);
        }
    }
}

Metode penelepon bisnis

    public async Task<ResultDTO> GetResultAsync(PostModel model)
    {
        try
        {
            using (var client = new WebApiClient())
            {
                var serializeModel= JsonConvert.SerializeObject(model);// using Newtonsoft.Json;
                var response = await client.PostJsonWithModelAsync<ResultDTO>("http://www.website.com/api/create", serializeModel);
                return response;
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }

    }
Bora Karaca
sumber
0

Inilah jawaban yang tepat:

public String sendSMS(String phone, String token) {
    WebClient webClient = WebClient.create(smsServiceUrl);

    SMSRequest smsRequest = new SMSRequest();
    smsRequest.setMessage(token);
    smsRequest.setPhoneNo(phone);
    smsRequest.setTokenId(smsServiceTokenId);

    Mono<String> response = webClient.post()
          .uri(smsServiceEndpoint)
          .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
          .body(Mono.just(smsRequest), SMSRequest.class)
          .retrieve().bodyToMono(String.class);

    String deliveryResponse = response.block();
    if (deliveryResponse.equalsIgnoreCase("success")) {
      return deliveryResponse;
    }
    return null;
}
KayV
sumber