.NET:发送带有数据的POST和读取响应的最简单方法


179

令我惊讶的是,在.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,并从Post静态类的方法返回响应Http

既然我们没有这么容易的事情,那么下一个最佳解决方案是什么?

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


Answers:


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

3
如果要对HTTP标头进行更多控制,则可以尝试使用HttpWebRequest并参考RFC2616(w3.org/Protocols/rfc2616/rfc2616.txt)。jball和BFree的回答都遵循了这一尝试。
克里斯·哈钦森

9
该示例实际上并未读取响应,这是原始问题的重要组成部分!
乔恩·瓦特

4
要阅读回复,您可以执行string result = System.Text.Encoding.UTF8.GetString(response)这是我找到答案的问题。
jporcenaluk 2014年

如果您尝试为Windows 8.1构建Windows应用商店应用程序,则此方法将不再起作用,因为在System.Net中找不到WebClient。而是使用Ramesh的答案,并研究“等待”的用法。
Stephen Wylie 2014年

2
我要加一,但是您应该在@jporcenaluk中加入有关阅读回复的评论,以改善您的答案。
Corgalore 2014年

78

使用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)
{


}

6
还可以使用Dictionary <String,String>使其更整洁。
Peter Hedberg

22
有史以来最好的答案..哦,感谢上帝,谢谢你,我爱你。我一直在挣扎.. 2怪胎周..你应该看到我所有的帖子。ARGHH的工作,YEHAAA <拥抱>
Jimmyt1988

1
请注意,在可能的情况下,请勿.ResultAsync调用一起使用-使用await以确保UI线程不会阻塞。同样,一个简单new[]的列表也将起作用。字典可以清除代码,但会减少某些HTTP功能。
Matt DeKrey 2014年

1
如今(2016年),这是最好的答案。HttpClient比WebClient更新(最受欢迎的答案),它具有一些优点:1)它具有一个很好的异步编程模型,该模型由基本上是HTTP的发明者之一的Henrik F Nielson使用,他设计了API,因此您很容易遵循HTTP标准;2).Net framework 4.5支持它,因此在可预见的将来,它具有一定保证水平的支持;3)如果您要在其他平台上使用它,则还具有库的xcopyable / portable-framework版本-.Net 4.0,Windows Phone等...
Luis Gouveia

如何使用httpclient发送文件
Darshan Dave

47

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

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

12

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

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

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

http://msdn.microsoft.com/zh-CN/library/tdbbwh0a(VS.80).aspx

UploadString()可能也可以正常工作,并且将其抽象了一个级别。

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


+1我怀疑在框架中有很多方法可以做到这一点。
jball

7

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

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?它给我一个错误“不存在”。
Rahul Khandelwal

6

鉴于其他答案已有数年历史,目前我的想法可能会有所帮助:

最简单的方法

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

5

您可以使用以下伪代码:

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.