将RestShapr RestRequest转换为本机HttpClient



我有这个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调用,看看你错过了什么。

相关内容

最新更新