.NET HttpClient。如何POST字符串值?

213
我该如何使用C#和HttpClient创建以下POST请求: User-Agent: Fiddler Content-type: application/x-www-form-urlencoded Host: localhost:6740 Content-Length: 6 我需要这样的请求用于我的WEB API服务:
[ActionName("exist")]
[HttpPost]
public bool CheckIfUserExist([FromBody] string login)
{           
    return _membershipProvider.CheckIfExist(login);
}

1
你在图像中使用了哪个HTTP客户端? - brimstone
http://www.telerik.com/fiddler - Ievgen Martynov
1
该服务是Web Api MVC。请求使用JSON格式吗? - Kiquenet
5个回答

492
在ASP.NET 4.5中(对于4.0版本,您需要安装Microsoft.AspNet.WebApi.Client NuGet包):
using System;
using System.Collections.Generic;
using System.Net.Http;

class Program
{
    static void Main(string[] args)
    {
        Task.Run(() => MainAsync());
        Console.ReadLine();
    }

    static async Task MainAsync()
    {
        var client = new HttpClient();
        client.BaseAddress = new Uri("http://localhost:6740");
        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("", "login")
        });
        var result = await client.PostAsync("/api/Membership/exists", content);
        string resultContent = await result.Content.ReadAsStringAsync();
        Console.WriteLine(resultContent);
    }
}

1
哦,我的 HttpClientExtensions 没有这样的重载... 我使用的是 4.0 框架。 - Ievgen Martynov
1
这是我遇到的第一个 C# SSSCE。如果你来自一个拥有适当 IDE 的语言,那么它就像轻而易举地运行起来一样。 - Buffalo
21
注意:在 using 语句中使用 HttpClient 是一个错误(参考链接:https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/)。 - ren
31
你应该使用私有静态只读的HttpClient _client = new HttpClient();而不是https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/中提到的方式。 - Sameer Alibhai
1
@Sameer 很好的观点..我推荐每个人都去查看那篇文章,它有一些严重的性能改进。 - Rajshekar Reddy
显示剩余3条评论

41
以下是同步调用的示例,但您可以轻松地通过使用 await-sync 进行更改为异步调用:
var pairs = new List<KeyValuePair<string, string>>
            {
                new KeyValuePair<string, string>("login", "abc")
            };

var content = new FormUrlEncodedContent(pairs);

var client = new HttpClient {BaseAddress = new Uri("http://localhost:6740")};

    // call sync
var response = client.PostAsync("/api/membership/exist", content).Result; 
if (response.IsSuccessStatusCode)
{
}

1
我认为这不会起作用。你应该用空字符串替换“login”,应该是KeyValuePair<string, string>("", "abc"),请参见已接受的答案。 - joedotnot
这对我有效,正在处理调用$company_id = $_POST("company_id"); 的PHP Web服务。如果我发送JSON格式,PHP将无法工作。 - TPG

29

这里我发现了一篇文章,介绍使用JsonConvert.SerializeObject()StringContent()发送POST请求到HttpClient.PostAsync数据的方法。

static async Task Main(string[] args)
{
    var person = new Person();
    person.Name = "John Doe";
    person.Occupation = "gardener";

    var json = Newtonsoft.Json.JsonConvert.SerializeObject(person);
    var data = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");

    var url = "https://httpbin.org/post";
    using var client = new HttpClient();

    var response = await client.PostAsync(url, data);

    string result = response.Content.ReadAsStringAsync().Result;
    Console.WriteLine(result);
}

9
在asp.net的网站上有一篇关于你问题的文章,希望它能对你有所帮助。
如何使用asp net调用api。

http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client

这是文章中POST部分的一个小节:
下面的代码发送一个包含以JSON格式表示的Product实例的POST请求:
// HTTP POST
var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" };
response = await client.PostAsJsonAsync("api/products", gizmo);
if (response.IsSuccessStatusCode)
{
    // Get the URI of the created resource.
    Uri gizmoUrl = response.Headers.Location;
}

请求是表单编码的,所以我认为 JSON 不适用。 - ChrisFletcher
它是form-urlencoded。无论如何,DateTime属性使用JSON格式会有序列化问题吗? - Kiquenet
5
我似乎没有注意到你的"PostAsJsonAsync" 方法,在我的HttpClient实例中不可用。 - Morgeth888

2
您可以像这样做:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:6740/api/Membership/exist");

req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";         
req.ContentLength = 6;

StreamWriter streamOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
streamOut.Write(strRequest);
streamOut.Close();
StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());
string strResponse = streamIn.ReadToEnd();
streamIn.Close();

然后strReponse应该包含您的Web服务返回的值。


29
这里的问题是如何使用新的 HttpClient 而不是旧的 WebRequest - Darin Dimitrov
我没有注意到,不过我还是会发布这篇文章,以防有人需要旧版本... - Axel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接