【问题标题】:How to post data to specific URL using WebClient in C#如何在 C# 中使用 WebClient 将数据发布到特定 URL
【发布时间】:2011-07-21 01:34:23
【问题描述】:

我需要使用带有 WebClient 的“HTTP Post”将一些数据发布到我拥有的特定 URL。

现在,我知道这可以通过 WebRequest 来完成,但由于某些原因,我想改用 WebClient。那可能吗?如果是这样,有人可以给我一些例子或指出正确的方向吗?

【问题讨论】:

    标签: c# post webclient


    【解决方案1】:

    我刚刚找到了解决方案,是的,它比我想象的要容易:)

    所以这里是解决方案:

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

    它的作用就像魅力:)

    【讨论】:

    • 吹毛求疵:最好在这里使用HttpRequestHeader.ContentType枚举成员web.Headers[HttpRequestHeader.ContentType]:p
    • 另一个挑剔,您应该使用 .dispose 或“使用”成语正确处理 webclient: using (WebClient wc = new WebClient()) { //your code here }
    • @RobinVanPersi 我认为 ShikataGanai (Rafik bari) 意味着另一个答案 (stackoverflow.com/a/13061805/1160796) 更好,因为它会为您处理编码。
    • @alpsystems.com IDisposable 对象需要由程序员正确处理,方法是包装在 using 中或显式调用 .Dispose()。垃圾收集器无法跟踪非托管资源,如文件处理程序、数据库连接等
    • 扩展@ccalboni 的解释。在某些情况下,垃圾收集器会通过调用析构函数来清理非托管资源等(例如,WebClient 继承自 Component,其中包含 ~Component() {Dispose(false);})。问题是垃圾收集器可能需要任意长的时间才能这样做,因为它在做出收集决定时没有考虑非托管资源。必须尽快清理高价值资源。例如,打开不需要的文件句柄可能会阻止文件被其他代码删除或写入。
    【解决方案2】:

    有一个名为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);
    }
    

    【讨论】:

    • 如果我想将模型发布到控制器怎么办?我还能使用 reqparm.Add(string, string) 吗?
    • @BurakKarakuş 你的意思是你想在正文中发送 JSON 吗?那么你可能想使用WebClient.UploadString。不要忘记在标题中添加 Content-Type: application/json。
    • @EndyTjahjono :如何发布单选按钮值。假设我有 3 个单选按钮属于同一组。
    • 如何获取响应码?响应头?我必须解析响应吗?有没有简单的方法可以做到这一点?
    • 警告。 namevalueCollection 不允许相同的键。因此可能会导致奇怪的问题
    【解决方案3】:

    使用WebClient.UploadStringWebClient.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/

    【讨论】:

    • 更好用:client.Encoding = System.Text.UTF8Encoding.UTF8; string varValue = Uri.EscapeDataString(value);
    【解决方案4】:
    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));
    }
    

    【讨论】:

      【解决方案5】:
      //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());            
        }
      }
      

      【讨论】:

      • 使用异步版本是个好办法,以上都在发布并阻塞执行。
      • 删除双 __ 以修复 wc__UploadStringCompleted
      • 以上所有答案在测试中都可以正常工作,但在互联网较差的现实生活中,这是一个更好的答案。
      【解决方案6】:

      使用简单的client.UploadString(adress, content); 通常可以正常工作,但我认为应该记住,如果没有返回 HTTP 成功状态代码,则会抛出 WebException。我通常这样处理它以打印远程服务器返回的任何异常消息:

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

      【讨论】:

      • 谢谢你,奥格拉斯。我花了很多时间来查找错误,您的代码为我提供了更多信息来修复。
      【解决方案7】:

      使用带有模型的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);
              }
      
          }
      

      【讨论】:

        【解决方案8】:

        大多数答案都是旧的。只是想分享对我有用的东西。为了异步做事,即在 .NET 6.0 Preview 7 中使用 WebClient 异步将数据发布到特定 URL,.NET Core 和其他版本可以使用 WebClient.UploadStringTaskAsync Method 完成。

        使用命名空间System.Net; 和一个类ResponseType 来捕获来自服务器的响应,我们可以使用该方法将POST 数据发送到特定的URL。请确保在调用此方法时使用await 关键字

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

        【讨论】:

          【解决方案9】:

          这里是明确的答案:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-02-12
            • 1970-01-01
            • 2018-07-03
            • 2012-12-05
            • 1970-01-01
            • 1970-01-01
            • 2015-07-19
            • 2011-02-05
            相关资源
            最近更新 更多