Как разместить данные на определенный URL с помощью WebClient в C #

319

Мне нужно использовать «HTTP Post» с WebClient, чтобы опубликовать некоторые данные по конкретному URL, который у меня есть.

Теперь я знаю, что это можно сделать с помощью WebRequest, но по некоторым причинам я хочу использовать вместо него WebClient. Это возможно? Если так, может кто-нибудь показать мне какой-нибудь пример или указать мне правильное направление?

Солид Снейк
источник

Ответы:

374

Я только нашел решение, и да, это было легче, чем я думал :)

так вот решение:

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

это работает как шарм :)

Солид Снейк
источник
28
Придирка: лучше использовать HttpRequestHeader.ContentTypeчлен перечисления вот так web.Headers[HttpRequestHeader.ContentType]: p
Alex
12
Еще один случай: вы должны правильно распоряжаться веб-клиентом с помощью .dispose или идиомы «использования»: using (WebClient wc = new WebClient ()) {// ваш код здесь}
Майки Хогарт,
1
@RobinVanPersi Я думаю, что ShikataGanai (Rafik bari) имел в виду, что другой ответ ( stackoverflow.com/a/13061805/1160796 ) лучше, потому что он обрабатывает кодировку для вас.
Basher
3
@ alpsystems.com IDisposable объекты должны быть правильно расположены программистом, либо заключая их в использование, либо явно вызывая .Dispose (). Сборщик мусора не может отследить неуправляемые ресурсы, такие как обработчики файлов, соединения с базой данных и т. Д.
ccalboni
1
Чтобы расширить объяснение @ ccalboni. В некоторых случаях сборщик мусора очищает неуправляемые ресурсы и тому подобное, вызывая деструктор (например, WebClientнаследует от Component, который содержит ~Component() {Dispose(false);}). Проблема заключается в том, что сборщику мусора может потребоваться произвольно много времени, поскольку он не учитывает неуправляемые ресурсы при принятии решений о сборе. Ценные ресурсы должны быть очищены как можно скорее. Например, оставив открытым ненужный дескриптор файла, можно заблокировать удаление файла или запись другим кодом.
Брайан
362

Существует встроенный метод UploadValues, который может отправлять HTTP- запрос POST (или любые методы HTTP) И обрабатывает создание тела запроса (объединение параметров с символом «&» и экранирование символов с помощью URL-кодирования) в правильном формате данных формы:

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);
}
Энди Тяхджоно
источник
1
Что если я хочу опубликовать модель на контроллере? Могу ли я использовать reqparm.Add (string, string)?
Бурак Каракуш
6
@ BurakKarakuş ты имеешь ввиду, что хочешь отправить JSON в теле? Тогда вы можете использовать WebClient.UploadString . Не забудьте добавить Content-Type: application / json в шапку.
Энди Тяхджоно
@EndyTjahjono: Как я могу публиковать значения переключателей. Предположим, у меня есть 3 переключателя, принадлежащие к одной группе.
Асад Рефаи
Как я могу получить код ответа? Заголовки ответа? Нужно ли анализировать ответ? Есть ли простой способ сделать это?
Джей Салливан
ВНИМАНИЕ. namevalueCollection не может использовать тот же ключ. Это может привести к странному поведению
bh_earth0
40

Используя WebClient.UploadStringили WebClient.UploadDataвы можете легко размещать данные на сервере. Я покажу пример использования UploadData, поскольку UploadString используется так же, как 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);

больше: http://www.daveamenta.com/2008-05/c-webclient-usage/

Пранай Рана
источник
5
лучше использовать: client.Encoding = System.Text.UTF8Encoding.UTF8; string varValue = Uri.EscapeDataString (value);
Юрий Викулов
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));
}
Андрей
источник
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
источник
Использование асинхронной версии хорошо, все вышеперечисленное публикует и блокирует выполнение.
Хуан
удалить двойное __, чтобы исправить wc__UploadStringCompleted
Джоэл Дэвис
1
Все приведенные выше ответы будут хорошо работать при тестировании, но в реальной ситуации с плохим интернетом это лучший ответ.
Джоэл Дэвис
2

Использование simple client.UploadString(adress, content);обычно работает нормально, но я думаю, что следует помнить, что a WebExceptionбудет выдано, если не будет возвращен HTTP-код успешного состояния. Я обычно обрабатываю это так, чтобы напечатать любое сообщение об исключении, которое возвращает удаленный сервер:

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
источник
спасибо, Огглас. Я потратил много времени, чтобы найти ошибку, а твой код дает мне больше информации для исправления.
Кейт
1

Используя webapiclient с моделью отправьте запрос на сериализацию параметра 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);
        }
    }
}

Метод бизнес-звонка

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

    }
Бора Карака
источник
0

Вот четкий ответ:

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
источник