Como postar dados em um URL específico usando o WebClient em C #

319

Preciso usar "HTTP Post" com o WebClient para postar alguns dados em um URL específico que tenho.

Agora, eu sei que isso pode ser feito com o WebRequest, mas por alguns motivos, eu quero usar o WebClient. Isso é possível? Nesse caso, alguém pode me mostrar algum exemplo ou me indicar a direção certa?

SolidSnake
fonte

Respostas:

374

Acabei de encontrar a solução e sim, foi mais fácil do que eu pensava :)

então aqui está a solução:

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

funciona como charme :)

SolidSnake
fonte
28
A procurar defeitos: é melhor usar HttpRequestHeader.ContentTypemembro da enumeração aqui assim web.Headers[HttpRequestHeader.ContentType]: p
Alex
12
Outra procurar defeitos, você deve descartar o webclient usando adequadamente .Dispose ou "usando" idioma: using (WebClient wc = new WebClient ()) {// seu código aqui}
Mikey Hogarth
1
@RobinVanPersi Acho que ShikataGanai (Rafik bari) significou que a outra resposta ( stackoverflow.com/a/13061805/1160796 ) é melhor porque lida com a codificação para você.
basher
3
@ alpsystems.com Objetos IDisposable precisam ser descartados adequadamente pelo programador, seja envolto em um uso ou invocando explicitamente .Dispose (). Coletor de lixo não pode controlar recursos não gerenciados, como manipuladores de arquivos, conexões de banco de dados e assim por diante
ccalboni
1
Para estender a explicação de @ ccalboni. Em alguns casos, o coletor de lixo limpa recursos não gerenciados e similares, chamando o destruidor (por exemplo, WebClientherda de Component, que contém ~Component() {Dispose(false);}). O problema é que o coletor de lixo pode levar um tempo arbitrariamente longo para fazer isso, pois não considera os recursos não gerenciados ao tomar decisões de coleta. Recursos de alto valor devem ser limpos o mais rápido possível. Por exemplo, deixar em aberto um identificador de arquivo desnecessário pode impedir a exclusão ou gravação do arquivo por outro código.
Brian
362

Existe um método interno chamado UploadValues que pode enviar HTTP POST (ou qualquer tipo de método HTTP) E lida com a construção do corpo da solicitação (concatenando parâmetros com "&" e caracteres de escape pela codificação de URL) no formato de dados de formulário apropriado:

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
fonte
1
E se eu quiser postar um modelo no controlador? Ainda posso usar reqparm.Add (string, string)?
Burak Karakuş
6
@ BurakKarakuş, você quer dizer que deseja enviar JSON no corpo? Em seguida, convém usar WebClient.UploadString . Não esqueça de adicionar Content-Type: application / json no cabeçalho.
Endy Tjahjono
@EndyTjahjono: Como posso postar valores de botões de opção. Suponha que eu tenho 3 botões de opção pertencem ao mesmo grupo.
Asad Refai
Como obtenho código de resposta? Cabeçalhos de resposta? Eu tenho que analisar a resposta? Existe uma maneira fácil de fazer isso?
Jay Sullivan
AVISO . NameValueCollection donest permitir mesmos .Assim-chave pode levar begaiviour estranho
bh_earth0
40

Usando WebClient.UploadStringou WebClient.UploadDatavocê pode enviar dados para o servidor facilmente. Vou mostrar um exemplo usando UploadData, já que UploadString é usado da mesma maneira que 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);

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

Pranay Rana
fonte
5
melhor usar: client.Encoding = System.Text.UTF8Encoding.UTF8; string varValue = Uri.EscapeDataString (valor);
Yuriy Vikulov 23/03
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
fonte
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
fonte
O uso da versão assíncrona é bom, todos os itens acima estão postando e bloqueando a execução.
Juan
eliminar a dupla __ a correção wc__UploadStringCompleted
Joel Davis
1
Todas as respostas acima funcionarão bem nos testes, mas em uma situação da vida real com pouca internet, essa é uma resposta melhor.
Joel Davis
2

Usar simple client.UploadString(adress, content);normalmente funciona bem, mas acho que deve ser lembrado que um WebExceptionserá lançado se não for retornado um código de status HTTP bem-sucedido. Eu costumo lidar com isso assim para imprimir qualquer mensagem de exceção que o servidor remoto está retornando:

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
fonte
obrigado, Ogglas. Gastei muito tempo para encontrar erros e seu código me fornece mais informações para corrigir.
Kate
1

O uso do webapiclient com modelo envia a solicitação de parâmetro serialize json.

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

Método de chamada comercial

    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
fonte
0

Aqui está a resposta nítida:

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
fonte