我有这个REST请求;我试着把它转化成HttpClient
。我不想在我的应用程序中使用RestSharp
。
我不知道如何在请求中发送一个空体:我不断收到"错误的请求";
基本上,我调用post
方法来登录下面的用户。它可以在RestSharp中工作,但是请求需要一个空体才能成功。
var client = new RestClient(Token.Location + "/users/api/login");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", Token.Value);
request.AddHeader("Content-Type", "application/json");
request.AddJsonBody(JsonSerializer.Serialize(new { }));
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
我正试图将这段代码转换为在。net core 3.1中使用HttpClient
。
这是我尝试过的:
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", Token.Value);
var stringContent = new StringContent(string.Empty);
var res = await client.PostAsync(Token.Location + "/users/api/login", stringContent);
var data = await res.Content.ReadAsStringAsync();
我也试过
...
var content = new StringContent(JsonSerializer.Serialize(new { }), Encoding.UTF8, "application/json");
var res = await client.PostAsync(Token.Location + "/users/api/login", content);
...
var res = await client.PostAsync(Token.Location + "/users/api/login", null);
...
var res = await client.PostAsync(Token.Location + "/users/api/login", "Empty string");
我总是收到"不好的请求"。因为我不会送一具空尸体过去。我试过邮差,它与{}
的空生体一起工作。我遗漏了什么?
您要做的第一件事是确保您正在使用共享的HttpClient。如果你使用ASP。. NET Core,使用IHttpClientFactory
。你可以在这里了解原因。
既然你要共享你的HttpClient
,最好不要使用DefaultReqestHeaders
,因为它会影响所有的请求,而且头字典不是线程安全的。因此,如果一个线程在修改集合的同时另一个线程在修改集合,您将崩溃。
DefaultRequestHeaders
。如果您不想一遍又一遍地设置相同的标题,它们很方便。设置一次,所有请求共享该值。
考虑到这一点,使用SendAsync
总是好的。这个方法接受一个HttpRequestMessasage
,它允许你将头分离到那个请求。
一个典型的使用场景是:
using (var req = new HttpRequestMessage(HttpMethod.Get,
new Uri("https://www.example.com")))
{
req.Headers.Authorization = new AuthenticationHeaderValue("token");
using (var resp = await _client.SendAsync(req))
{
resp.EnsureSuccessStatusCode();
var data = resp.Content.ReadAsStringAsync();
}
}
这将发送一个GET请求到https://www.example.com
,Authorization
报头值为token
。
HttpRequestMessage
有自己的一组头,与DefaultRequestHeaders
一起使用。
下一件要考虑的事情,这超出了你的问题范围,但值得提出:在用片段创建url时尝试使用UriBuilder
。
例如:
var uri = new UriBuilder(Token.Location) { Path = "/users/api/login" }.Uri;
现在您不必担心Token.Location
是否以/
结尾。框架将确保它是格式良好的。
至于将对象作为JSON发布,这里有一个使用Newtonsoft.Json
包的示例:
using (var req = new HttpRequestMessage(HttpMethod.Post,
new Uri("https://www.example.com")))
{
req.Headers.Authorization = new AuthenticationHeaderValue("token");
req.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
req.Content = new StringContent(
JsonConvert.SerializeObject(theObjectToSend),
Encoding.UTF8,
"application/json");
using (var resp = await _client.SendAsync(req))
{
resp.EnsureSuccessStatusCode();
var data = JsonConvert.DeserializeObject<object>(
await resp.Content.ReadAsStringAsync());
}
}
这将序列化并将适当的标头应用于您的请求。然后,它将读取请求并将其反序列化到object
。您可能希望用您创建的模型替换object
,以便易于阅读。
我知道这个答案对于你所问的问题有些夸张,但是当人们第一次开始使用HttpClient
时,我喜欢给一些提示,因为有一些"抓到你"。
因此,对于您的答案,采用上面的代码并将theObjectToSend
替换为new {}
,看看会发生什么。
如果它仍然不工作,使用Fiddler之类的东西来调试你的HTTP调用,看看你错过了什么。