C#: 使用HttpClient发送POST请求并传递参数

44

我使用下面的代码向服务器发送POST请求:

string url = "http://myserver/method?param1=1&param2=2"    
HttpClientHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
HttpResponseMessage response = await httpClient.SendAsync(request);

我无法访问服务器进行调试,但我想知道,这个请求是作为POST还是GET发送的?

如果是GET,我要如何更改代码以将param1和param2作为POST数据发送(而不是在URL中)?


3
这句话是将一条POST请求发送到url, 通过传入HttpMethod.Post来创建一个POST请求。那么,param1和param2是什么? - Ben Robinson
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Vahid
@SandySands 谢谢。它在Windows Phone模拟器中,很难为Fiddler配置它。 - Vahid
4个回答

88
一个更加简洁的替代方案是使用 Dictionary 来处理参数。毕竟它们都是键值对。
private static readonly HttpClient httpclient;

static MyClassName()
{
    // HttpClient is intended to be instantiated once and re-used throughout the life of an application. 
    // Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. 
    // This will result in SocketException errors.
    // https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netframework-4.7.1
    httpclient = new HttpClient();    
} 

var url = "http://myserver/method";
var parameters = new Dictionary<string, string> { { "param1", "1" }, { "param2", "2" } };
var encodedContent = new FormUrlEncodedContent (parameters);

var response = await httpclient.PostAsync (url, encodedContent).ConfigureAwait (false);
if (response.StatusCode == HttpStatusCode.OK) {
    // Do something with response. Example get content:
    // var responseContent = await response.Content.ReadAsStringAsync ().ConfigureAwait (false);
}

同时不要忘记使用关键字using释放HttpClient。

Microsoft文档中HttpClient类的备注部分所述,应该实例化一次并重复使用HttpClient。

编辑:

您可能需要查看response.EnsureSuccessStatusCode();而不是if (response.StatusCode == HttpStatusCode.OK)

您可能希望保留您的httpclient而不Dispose()它。请参见:HttpClient和HttpClientHandler是否必须被释放?

编辑:

不用担心在.NET Core中使用.ConfigureAwait(false)。有关更多详情,请参见https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html

3
这个版本对我没用。控制器动作接收的参数始终为空。 - d00d
@d00d 可以随意发布一个与此问题相关联的新问题,解释你的问题。 - aloisdg
发送带参数的Get请求怎么样? - Hosein Aqajani
@HoseinAqajani 我认为这将是一个很好的问题,可以在新帖子中提出。请随意在此处作为评论链接。 - aloisdg
1
List<KeyValuePair<string, string>> 作为查询参数键不一定唯一,更加简洁。 - Beltway
虽然你说得没错(所以我给你点了个赞),但我不喜欢带有重复参数的查询。我不仅仅编写.NET代码,而且由于没有关于此的规范,不同的服务器会以不同的方式处理重复。此外,重复可能会导致HPP问题。 - aloisdg

0
查询是否以POST方式发送的答案是,是的 - 查询是以POST方式发送的。
如果服务器是ASP.NET Web API,并且服务器未看到查询,请确保使用[FromQuery]修饰参数(将其作为主体发送应该使用[FromBody]或[FromForm])。

0

这是我在依赖注入中的使用方式:

using HttpClient httpClient = clientFactory.CreateClient("name set in builder host");
// httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"Token {token}");
HttpResponseMessage? res = await httpClient!.PostAsync(url, content);
try
{
    res.EnsureSuccessStatusCode();
    return res;
}
catch (Exception)
{
    // Add error handling
}

内容是:

List<KeyValuePair<string, string>> values = new()
{
    new KeyValuePair<string, string>("data", "value")
};
FormUrlEncodedContent requestContent = new(values);

而 clientFactory 是接口:

IHttpClientFactory

MSDN 接口


-8

正如Ben所说,您正在POST请求(在您的代码中指定了HttpMethod.Post)

包含在您的URL中的查询字符串(get)参数可能不起作用。

尝试这个:

string url = "http://myserver/method";    
string content = "param1=1&param2=2";
HttpClientHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
HttpResponseMessage response = await httpClient.SendAsync(request,content);

HTH,

bovako


1
@JohnCroneh,这个方法已经不再适用了。请接受下面的其他答案! - Mark Szabo
1
@JohnCroneh请将已接受的答案更改为有效的答案。 - R. McManaman
3
实际上,如果您采用创建一个未知方法类型的方法,这是一个很好的答案。它缺少一些“using”以确保它被处理并且需要进行“确保转换”,但它遵循了PostAsync包装器实现。 - HellBaby

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