How to post data to specific URL using WebClient in C#
Asked Answered
D

9

349

I need to use "HTTP Post" with WebClient to post some data to a specific URL I have.

Now, I know this can be accomplished with WebRequest but for some reasons I want to use WebClient instead. Is that possible? If so, can someone show me some example or point me to the right direction?

Dardanelles answered 23/3, 2011 at 6:15 Comment(0)
D
402

I just found the solution and yea it was easier than I thought :)

so here is the solution:

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

it works like charm :)

Dardanelles answered 23/3, 2011 at 6:29 Comment(14)
A nitpick: it's better to use HttpRequestHeader.ContentType enumeration member here like this web.Headers[HttpRequestHeader.ContentType] :pAdvised
Another nitpick, you should dispose of the webclient properly using .dispose or the "using" idiom: using (WebClient wc = new WebClient()) { //your code here }Proportional
How are you saving the response into the string HtmlResult in this statement while UploadString(URI, myParameters); return type is void. string HtmlResult = wc.UploadString(URI, myParameters);Hellion
@ShikataGaNai - you need to encode the values of the params and you are good to go.Dardanelles
@RobinVanPersi I think ShikataGanai (Rafik bari) meant that the other answer (https://mcmap.net/q/92951/-how-to-post-data-to-specific-url-using-webclient-in-c) is better because it handles the encoding for you.Chilt
Why does it need "using"? The .NET garbage collection isn't good enough? Does the TCP-IP connection stay open or something like that?Bobbobb
@alpsystems.com IDisposable objects need to be properly disposed by programmer, either by wrapping within a using or by explicitly invoking .Dispose(). Garbage collector can't track unmanaged resources, like file handlers, database connections and so onModie
To extend @ccalboni's explanation. In some cases the garbage collector will clean up unmanaged resources and the like by calling the destructor (e.g., WebClient inherits from Component, which contains ~Component() {Dispose(false);}). The problem is that the garbage collector may take an arbitrarily long time to do so, since it does not account for unmanaged resources when making collection decisions. High-value resources must be cleaned up as soon as possible. For example, leaving open an unneeded file handle could block the file from being deleted or written to by other code.Caloyer
In asp.net web api, it doesn't work this way. The Post type API will not accept this requestZak
I want to send the payload via post method, using UploadString sends that payload as content of the file. Can someone let me know what function to use to construct payload which have file properties like name etcLycopodium
UploadString POSTS by defaultMahla
How can i pass two different values to same parameter ? I tried something like this bit it did not work. using (WebClient wc = new WebClient()) { wc.QueryString.Add("wt", "json"); wc.QueryString.Add("fq", domain); wc.QueryString.Add("fq", orgs); wc.QueryString.Add("indent", "true"); // This line gives error - Bad Request - it appends comma after 1st parameter.how this can be resolved ? data = wc.UploadValues(uri, "POST", wc.QueryString);Hetti
What if the response from the server is not plain text? Like a PDF or image?Corpora
For me, the correct way using GET was: webclient.DownloadString(string.Format("{0}?{1}", uri, parameters));Nock
H
379

There is a built in method called UploadValues that can send HTTP POST (or any kind of HTTP methods) AND handles the construction of request body (concatenating parameters with "&" and escaping characters by url encoding) in proper form data format:

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);
}
Hellen answered 25/10, 2012 at 4:55 Comment(9)
What if I want to post a model to controller? Can I still use reqparm.Add(string, string)?Saddlebag
@BurakKarakuş do you mean you want to send JSON in the body? Then you may want to use WebClient.UploadString. Don't forget to add Content-Type: application/json in the header.Hellen
@EndyTjahjono : How can I post radio button values. Assume I have 3 radio buttons belong to same group.Casebook
How do I get response code? Response headers? Do I have to parse the response? Is there an easy way to do that?Marconigraph
WARNİNG . namevalueCollection donest allow same key .thus may lead weird begaiviourMoorings
I prefer this way because the parameters are escaped automagicallyHayfield
NameValueCollection will not work properly with arrays. If multiple parameters with the same key will be added, they will be joined and coma delimited. When posted, server will treat them as a single string.Frith
This should be the selected answer IMHO.Wist
What if the response from the server is not plain text? Like a PDF or image?Corpora
A
43

Using WebClient.UploadString or WebClient.UploadData you can POST data to the server easily. I’ll show an example using UploadData, since UploadString is used in the same manner as 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);

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

Aprilaprile answered 23/3, 2011 at 6:18 Comment(1)
better to use: client.Encoding = System.Text.UTF8Encoding.UTF8; string varValue = Uri.EscapeDataString(value);Balmoral
P
28
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));
}
Pristine answered 1/8, 2016 at 23:8 Comment(0)
S
23
//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());            
  }
}
Sharronsharyl answered 21/8, 2012 at 13:24 Comment(3)
Using the async version is a good one all of the above are posting and blocking the execution.Purposive
remove double __ to fix wc__UploadStringCompletedRembrandt
All above answers will work fine in testing, but in a real life situation with poor internet this is a better answer.Rembrandt
T
5

Using simple client.UploadString(adress, content); normally works fine but I think it should be remembered that a WebException will be thrown if not a HTTP successful status code is returned. I usually handle it like this to print any exception message the remote server is returning:

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;
}
Tuscarora answered 14/3, 2019 at 14:21 Comment(1)
thank you, Ogglas. I spent a lot of time to find error and your code gives me more information to fix.Turnover
C
3

Using webapiclient with model send serialize json parameter request.

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

Business caller method

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

    }
Corbie answered 1/10, 2019 at 8:20 Comment(0)
L
1

Most of the answers are old. Just wanted to share what worked for me. In the interest of doing things asynchronously i.e. to post data to specific URL using WebClient asynchronously in .NET 6.0 Preview 7, .NET Core and other versions can be done using WebClient.UploadStringTaskAsync Method.

Use namespace System.Net; and for a class ResponseType to capture the response from the server, we can use this method to POST data to a specific URL. Make sure to use the await keyword while calling this method

    public async Task<ResponseType> MyAsyncServiceCall()
    {
        try
        {
            var uri = new Uri("http://your_uri");
            var body= "param1=value1&param2=value2&param3=value3";

            using (var wc = new WebClient())
            {
                wc.Headers[HttpRequestHeader.Authorization] = "yourKey"; // Can be Bearer token, API Key etc.....
                wc.Headers[HttpRequestHeader.ContentType] = "application/json"; // Is about the payload/content of the current request or response. Do not use it if the request doesn't have a payload/ body.
                wc.Headers[HttpRequestHeader.Accept] = "application/json"; // Tells the server the kind of response the client will accept.
                wc.Headers[HttpRequestHeader.UserAgent] = "PostmanRuntime/7.28.3"; 
                
                string result = await wc.UploadStringTaskAsync(uri, body);
                return JsonConvert.DeserializeObject<ResponseType>(result);
            }
        }
        catch (Exception e)
        {
            throw new Exception(e.Message);
        }
    }
Limousine answered 21/8, 2021 at 2:33 Comment(0)
S
0

Here is the crisp answer:

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;
}
Shrubbery answered 2/6, 2020 at 16:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.