วิธีโพสต์ข้อมูลไปยัง 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
nitpick: ดีกว่าที่จะใช้การHttpRequestHeader.ContentTypeแจงนับสมาชิกที่นี่เช่นนี้web.Headers[HttpRequestHeader.ContentType]: p
Alex

12
nitpick อื่นคุณควรกำจัด webclient อย่างถูกต้องโดยใช้. disdispos หรือ "ใช้" สำนวน: การใช้ (WebClient wc = WebClient ใหม่ ()) {// รหัสของคุณที่นี่}
Mikey Hogarth

1
@RobinVanPersi ฉันคิดว่า ShikataGanai (Rafik bari) หมายความว่าคำตอบอื่น ๆ ( stackoverflow.com/a/13061805/1160796 ) ดีกว่าเพราะจัดการการเข้ารหัสสำหรับคุณ
basher

3
@ alpsystems.com ออบเจ็กต์ IDisposable ต้องถูกกำจัดอย่างเหมาะสมโดยโปรแกรมเมอร์ไม่ว่าจะเป็นการตัดภายในการใช้งานหรือโดยการเรียกใช้ .Dispose () อย่างชัดเจน ตัวรวบรวมขยะไม่สามารถติดตามทรัพยากรที่ไม่มีการจัดการเช่นตัวจัดการไฟล์การเชื่อมต่อฐานข้อมูลและอื่น ๆ
ccalboni

1
หากต้องการขยายคำอธิบาย @ ccalboni ในบางกรณีตัวเก็บรวบรวมขยะจะล้างทรัพยากรที่ไม่มีการจัดการและสิ่งที่คล้ายกันโดยการเรียกผู้ทำลายล้าง (เช่นWebClientสืบทอดมาจากComponentที่มี~Component() {Dispose(false);}) ปัญหาคือตัวรวบรวมขยะอาจใช้เวลานานในการดำเนินการเนื่องจากมันไม่ได้พิจารณาถึงทรัพยากรที่ไม่มีการจัดการเมื่อทำการตัดสินใจในการรวบรวม ทรัพยากรที่มีมูลค่าสูงจะต้องทำความสะอาดให้เร็วที่สุด ตัวอย่างเช่นการปล่อยให้เปิดการจัดการไฟล์ที่ไม่จำเป็นสามารถบล็อกไฟล์จากการถูกลบหรือเขียนโดยรหัสอื่น
Brian

361

มีวิธีการในตัวที่ชื่อว่า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) ได้หรือไม่
Burak Karakuş

6
@ BurakKarakuşคุณหมายถึงต้องการส่ง JSON เข้าสู่ร่างกายหรือไม่? แล้วคุณอาจต้องการที่จะใช้WebClient.UploadString อย่าลืมเพิ่มประเภทเนื้อหา: application / json ในส่วนหัว
จบ Tjahjono

@EndyTjahjono: ฉันจะโพสต์ค่าปุ่มตัวเลือกได้อย่างไร สมมติว่าฉันมีปุ่มตัวเลือก 3 ปุ่มอยู่ในกลุ่มเดียวกัน
ซาด Refai

ฉันจะรับรหัสตอบกลับได้อย่างไร ส่วนหัวการตอบสนองหรือไม่ ฉันต้องแยกวิเคราะห์คำตอบหรือไม่? มีวิธีง่าย ๆ ที่จะทำเช่นนั้น?
Jay Sullivan

คำเตือน . namevalueCollection donest อนุญาตให้ใช้คีย์เดียวกันดังนั้นจึงอาจนำไปสู่ ​​begaiviour แปลก ๆ
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 (ค่า);
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));
}

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

การใช้เวอร์ชัน async เป็นสิ่งที่ดีสิ่งที่กล่าวมาทั้งหมดข้างต้นกำลังโพสต์และบล็อกการดำเนินการ
Juan

ลบ double __ เพื่อแก้ไข wc__UploadStringCompleted
Joel Davis

1
คำตอบทั้งหมดข้างต้นจะทำงานได้ดีในการทดสอบ แต่ในสถานการณ์จริงกับอินเทอร์เน็ตที่ไม่ดีนี่เป็นคำตอบที่ดีกว่า
Joel Davis

2

ใช้ง่าย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;
}

ขอบคุณ Ogglas ฉันใช้เวลามากมายในการค้นหาข้อผิดพลาดและรหัสของคุณให้ข้อมูลเพิ่มเติมแก่ฉันเพื่อแก้ไข
Kate

1

การใช้ webapiclient กับ model ส่งคำร้องขอพารามิเตอร์ 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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.