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

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

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


person SolidSnake    schedule 23.03.2011    source источник


Ответы (7)


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

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

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

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

person SolidSnake    schedule 23.03.2011
comment
Придирка: лучше использовать член перечисления HttpRequestHeader.ContentType вот так web.Headers[HttpRequestHeader.ContentType]: p - person Alex; 12.04.2012
comment
Еще одна придирка: вы должны правильно избавиться от веб-клиента, используя .dispose или идиому using: using (WebClient wc = new WebClient ()) {// здесь ваш код} - person Mikey Hogarth; 16.05.2012
comment
Как вы сохраняете ответ в строке HtmlResult в этом операторе, пока UploadString (URI, myParameters); тип возврата недействителен. строка HtmlResult = wc.UploadString (URI, myParameters); - person Ashish-BeJovial; 07.02.2014
comment
@ShikataGaNai - вам нужно закодировать значения параметров, и все готово. - person SolidSnake; 13.08.2014
comment
@RobinVanPersi Я думаю, что ShikataGanai (Рафик Бари) означал, что другой ответ (stackoverflow.com/a/13061805/1160796) - лучше, потому что он обрабатывает кодировку за вас. - person basher; 04.09.2014
comment
Зачем это нужно? Сборка мусора .NET недостаточно хороша? Соединение TCP-IP остается открытым или что-то в этом роде? - person alpsystems.com; 29.11.2015
comment
@ alpsystems.com IDisposable объекты должны быть должным образом удалены программистом, либо путем обертывания внутри using, либо путем явного вызова .Dispose (). Сборщик мусора не может отслеживать неуправляемые ресурсы, такие как обработчики файлов, подключения к базе данных и т. Д. - person ccalboni; 01.06.2016
comment
Чтобы расширить объяснение @ccalboni. В некоторых случаях сборщик мусора очищает неуправляемые ресурсы и тому подобное, вызывая деструктор (например, WebClient наследуется от Component, который содержит ~Component() {Dispose(false);}). Проблема в том, что сборщику мусора может потребоваться сколь угодно много времени для этого, поскольку он не учитывает неуправляемые ресурсы при принятии решений о сборке. Ценные ресурсы должны быть очищены как можно скорее. Например, если оставить открытым ненужный дескриптор файла, это может помешать удалению или записи файла другим кодом. - person Brian; 11.01.2017
comment
В веб-API asp.net это не работает. API типа сообщения не примет этот запрос - person Lali; 16.07.2018
comment
Я хочу отправить полезные данные с помощью метода post, используя UploadString, который отправляет эти полезные данные как содержимое файла. Может ли кто-нибудь сообщить мне, какую функцию использовать для создания полезной нагрузки, которая имеет свойства файла, такие как имя и т. Д. - person Susarla Nikhilesh; 23.08.2018
comment
UploadString POSTS по умолчанию - person Greg; 12.09.2018
comment
Как передать два разных значения одному и тому же параметру? Я пробовал что-то вроде этого, не получилось. используя (WebClient wc = new WebClient ()) {wc.QueryString.Add (wt, json); wc.QueryString.Add (fq, домен); wc.QueryString.Add (fq, orgs); wc.QueryString.Add (отступ, истина); // Эта строка выдает ошибку - Плохой запрос - она ​​добавляет запятую после 1-го параметра. Как это можно решить? data = wc.UploadValues ​​(uri, POST, wc.QueryString); - person user662285; 01.10.2018
comment
Что делать, если ответ от сервера не является обычным текстом? Нравится PDF или изображение? - person joym8; 04.03.2020

Существует встроенный метод, называемый 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);
}
person Endy Tjahjono    schedule 25.10.2012
comment
Что, если я хочу опубликовать модель в контроллере? Могу ли я использовать reqparm.Add (строка, строка)? - person Burak Karakuş; 13.04.2015
comment
@ BurakKarakuş Вы имеете в виду, что хотите отправить JSON в теле? Затем вы можете использовать WebClient.UploadString . Не забудьте добавить Content-Type: application / json в заголовок. - person Endy Tjahjono; 17.04.2015
comment
@EndyTjahjono: Как я могу разместить значения переключателей. Предположим, у меня есть 3 переключателя, принадлежащих одной группе. - person Asad Refai; 04.08.2015
comment
Как мне получить код ответа? Заголовки ответа? Нужно ли разбирать ответ? Есть простой способ сделать это? - person Jay Sullivan; 09.11.2016
comment
ПРЕДУПРЕЖДЕНИЕ . namevalueCollection donest позволяет использовать один и тот же ключ. это может привести к странному началу - person bh_earth0; 18.01.2017
comment
Я предпочитаю этот способ, потому что параметры экранируются автоматически - person vcRobe; 13.02.2017
comment
NameValueCollection не будет правильно работать с массивами. Если будет добавлено несколько параметров с одним и тем же ключом, они будут объединены и разделены запятыми. После публикации сервер будет рассматривать их как одну строку. - person jahu; 07.09.2018
comment
Это должен быть выбранный ответ ИМХО. - person MemphiZ; 13.08.2019
comment
Что делать, если ответ от сервера не является обычным текстом? Нравится PDF или изображение? - person joym8; 04.03.2020

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

person Pranay Rana    schedule 23.03.2011
comment
лучше использовать: client.Encoding = System.Text.UTF8Encoding.UTF8; строка varValue = Uri.EscapeDataString (значение); - person Yuriy Vikulov; 23.03.2011

Использование простого client.UploadString(adress, content); обычно работает нормально, но я думаю, следует помнить, что 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;
}
person Ogglas    schedule 14.03.2019
comment
спасибо, Огглас. Я потратил много времени, чтобы найти ошибку, и ваш код дает мне больше информации, которую нужно исправить. - person Kate; 11.07.2019

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

Метод делового звонящего

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

    }
person Bora Karaca    schedule 01.10.2019

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

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;
}
person KayV    schedule 02.06.2020

person    schedule
comment
Использование асинхронной версии - хороший вариант: все вышеперечисленное публикует и блокирует выполнение. - person Juan; 30.07.2015
comment
удалите двойной __, чтобы исправить wc__UploadStringCompleted - person Joel Davis; 15.09.2016
comment
Все приведенные выше ответы будут отлично работать при тестировании, но в реальной ситуации с плохим интернетом это лучший ответ. - person Joel Davis; 15.09.2016