【问题标题】:.NET: Simplest way to send POST with data and read response.NET:发送带有数据的 POST 并读取响应的最简单方法
【发布时间】:2011-05-04 13:39:55
【问题描述】:

令我惊讶的是,据我所知,在 .NET BCL 中,我无法做如此简单的事情:

byte[] response = Http.Post
(
    url: "http://dork.com/service",
    contentType: "application/x-www-form-urlencoded",
    contentLength: 32,
    content: "home=Cosby&favorite+flavor=flies"
);

上面的这个假设代码生成一个带有数据的 HTTP POST,并从静态类 Http 上的 Post 方法返回响应。

既然我们没有这么简单的东西,那么下一个最佳解决方案是什么?

如何发送带有数据的 HTTP POST 并获取响应的内容?

【问题讨论】:

标签: c# .net http http-post httpresponse


【解决方案1】:
   using (WebClient client = new WebClient())
   {

       byte[] response =
       client.UploadValues("http://dork.com/service", new NameValueCollection()
       {
           { "home", "Cosby" },
           { "favorite+flavor", "flies" }
       });

       string result = System.Text.Encoding.UTF8.GetString(response);
   }

您将需要这些包括:

using System;
using System.Collections.Specialized;
using System.Net;

如果您坚持使用静态方法/类:

public static class Http
{
    public static byte[] Post(string uri, NameValueCollection pairs)
    {
        byte[] response = null;
        using (WebClient client = new WebClient())
        {
            response = client.UploadValues(uri, pairs);
        }
        return response;
    }
}

那么简单:

var response = Http.Post("http://dork.com/service", new NameValueCollection() {
    { "home", "Cosby" },
    { "favorite+flavor", "flies" }
});

【讨论】:

  • 如果您想要更多地控制 HTTP 标头,您可以尝试使用 HttpWebRequest 并参考 RFC2616 (w3.org/Protocols/rfc2616/rfc2616.txt)。来自 jball 和 BFree 的回答紧随其后。
  • 这个例子实际上并没有读取响应,这是原始问题的重要部分!
  • 要阅读回复,您可以使用string result = System.Text.Encoding.UTF8.GetString(response)This is the question where I found the answer.
  • 如果您尝试为 Windows 8.1 构建 Windows Store 应用程序,此方法将不再有效,因为在 System.Net 中找不到 WebClient。相反,请使用 Ramesh 的答案并查看“等待”的用法。
  • 我要加一个,但你应该包括@jporcenaluk 评论关于阅读回复以改进你的答案。
【解决方案2】:

使用 HttpClient:就 Windows 8 应用程序开发而言,我遇到了这个问题。

var client = new HttpClient();

var pairs = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string, string>("pqpUserName", "admin"),
        new KeyValuePair<string, string>("password", "test@123")
    };

var content = new FormUrlEncodedContent(pairs);

var response = client.PostAsync("youruri", content).Result;

if (response.IsSuccessStatusCode)
{


}

【讨论】:

  • 还可以与 Dictionary 一起使用,这样会更简洁。
  • 有史以来最好的答案.. 哦,谢谢各位大神,谢谢我爱你。我一直在挣扎.. 2 FREAKNG WEEKS.. 你应该看到我所有的帖子。啊,它在工作,耶哈
  • 请注意,如果可能,您不应将 .ResultAsync 调用一起使用 - 使用 await 以确保您的 UI 线程不会阻塞。此外,一个简单的new[] 将与列表一样工作;字典可能会清理代码,但会减少一些 HTTP 功能。
  • 现在(2016 年)这是最好的答案。 HttpClient 比 WebClient 更新(投票最多的答案),并且比它有一些好处:1)它有一个很好的异步编程模型,Henrik F Nielson 基本上是 HTTP 的发明者之一,他设计了 API,所以它便于您遵循 HTTP 标准; 2) 受.Net framework 4.5支持,因此对可预见的未来有一定的支持水平; 3) 如果您想在其他平台上使用它,它还具有库的 xcopyable/portable-framework 版本 - .Net 4.0、Windows Phone 等...
  • 如何使用httpclient发送文件
【解决方案3】:

使用WebRequest。来自Scott Hanselman

public static string HttpPost(string URI, string Parameters) 
{
   System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
   req.Proxy = new System.Net.WebProxy(ProxyString, true);
   //Add these, as we're doing a POST
   req.ContentType = "application/x-www-form-urlencoded";
   req.Method = "POST";
   //We need to count how many bytes we're sending. 
   //Post'ed Faked Forms should be name=value&
   byte [] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
   req.ContentLength = bytes.Length;
   System.IO.Stream os = req.GetRequestStream ();
   os.Write (bytes, 0, bytes.Length); //Push it out there
   os.Close ();
   System.Net.WebResponse resp = req.GetResponse();
   if (resp== null) return null;
   System.IO.StreamReader sr = 
         new System.IO.StreamReader(resp.GetResponseStream());
   return sr.ReadToEnd().Trim();
}

【讨论】:

    【解决方案4】:
    private void PostForm()
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://dork.com/service");
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        string postData ="home=Cosby&favorite+flavor=flies";
        byte[] bytes = Encoding.UTF8.GetBytes(postData);
        request.ContentLength = bytes.Length;
    
        Stream requestStream = request.GetRequestStream();
        requestStream.Write(bytes, 0, bytes.Length);
    
        WebResponse response = request.GetResponse();
        Stream stream = response.GetResponseStream();
        StreamReader reader = new StreamReader(stream);
    
        var result = reader.ReadToEnd();
        stream.Dispose();
        reader.Dispose();
    }
    

    【讨论】:

      【解决方案5】:

      就个人而言,我认为进行 http 发布并获得响应的最简单方法是使用 WebClient 类。这个类很好地抽象了细节。 MSDN 文档中甚至还有完整的代码示例。

      http://msdn.microsoft.com/en-us/library/system.net.webclient(VS.80).aspx

      在您的情况下,您需要 UploadData() 方法。 (同样,文档中包含代码示例)

      http://msdn.microsoft.com/en-us/library/tdbbwh0a(VS.80).aspx

      UploadString() 可能也能正常工作,它会将其抽象出一层。

      http://msdn.microsoft.com/en-us/library/system.net.webclient.uploadstring(VS.80).aspx

      【讨论】:

      • +1 我怀疑框架中有很多方法可以做到这一点。
      【解决方案6】:

      我知道这是一个旧线程,但希望它对某些人有所帮助。

      public static void SetRequest(string mXml)
      {
          HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.CreateHttp("http://dork.com/service");
          webRequest.Method = "POST";
          webRequest.Headers["SOURCE"] = "WinApp";
      
          // Decide your encoding here
      
          //webRequest.ContentType = "application/x-www-form-urlencoded";
          webRequest.ContentType = "text/xml; charset=utf-8";
      
          // You should setContentLength
          byte[] content = System.Text.Encoding.UTF8.GetBytes(mXml);
          webRequest.ContentLength = content.Length;
      
          var reqStream = await webRequest.GetRequestStreamAsync();
          reqStream.Write(content, 0, content.Length);
      
          var res = await httpRequest(webRequest);
      }
      

      【讨论】:

      • 什么是httpRequest?它给了我一个错误“不存在”。
      【解决方案7】:

      鉴于其他答案已经有几年了,目前我的想法可能会有所帮助:

      最简单的方法

      private async Task<string> PostAsync(Uri uri, HttpContent dataOut)
      {
          var client = new HttpClient();
          var response = await client.PostAsync(uri, dataOut);
          return await response.Content.ReadAsStringAsync();
          // For non strings you can use other Content.ReadAs...() method variations
      }
      

      一个更实际的例子

      我们经常处理已知类型和 JSON,因此您可以通过任意数量的实现进一步扩展这个想法,例如:

      public async Task<T> PostJsonAsync<T>(Uri uri, object dtoOut)
      {
          var content = new StringContent(JsonConvert.SerializeObject(dtoOut));
          content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
      
          var results = await PostAsync(uri, content); // from previous block of code
      
          return JsonConvert.DeserializeObject<T>(results); // using Newtonsoft.Json
      }
      

      如何调用它的示例:

      var dataToSendOutToApi = new MyDtoOut();
      var uri = new Uri("https://example.com");
      var dataFromApi = await PostJsonAsync<MyDtoIn>(uri, dataToSendOutToApi);
      

      【讨论】:

        【解决方案8】:

        你可以使用类似这样的伪代码:

        request = System.Net.HttpWebRequest.Create(your url)
        request.Method = WebRequestMethods.Http.Post
        
        writer = New System.IO.StreamWriter(request.GetRequestStream())
        writer.Write("your data")
        writer.Close()
        
        response = request.GetResponse()
        reader = New System.IO.StreamReader(response.GetResponseStream())
        responseText = reader.ReadToEnd
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-16
          • 1970-01-01
          相关资源
          最近更新 更多