将 RestShapr RestRequest 转换为原生 HttpClient
Convert RestShapr RestRequest to native 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");
我不断收到“错误请求”,因为我发送的不是空的正文。
我已经在邮递员中尝试过,它适用于 {}
的空原始主体。我在这里错过了什么?
您要做的第一件事是确保您使用的是 shared HttpClient. If you are in ASP.NET Core, use IHttpClientFactory
. You can learn why here。
既然你要分享你的HttpClient
,最好不要使用DefaultReqestHeaders
,因为它会影响所有请求,header 字典不是 thread-safe。因此,如果一个线程正在修改 collection,同时另一个线程正在修改,您将崩溃。
这并不是说您应该永远使用DefaultRequestHeaders
。如果您不想一遍又一遍地设置相同的 header,它们会很方便。您设置一次该值,所有请求都共享该值。
考虑到这一点,使用 SendAsync
总是好的。此方法采用 HttpRequestMessasage
,它允许您将 header 隔离到那个请求。
一个典型的使用场景是:
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();
}
}
这将向 https://www.example.com
发送 GET 请求,其中 Authorization
header 的值为 token
.
HttpRequestMessage
有自己的一组 header 与 DefaultRequestHeaders
结合使用。
接下来要考虑的事情,这超出了您的问题范围,但值得提出:尝试使用 UriBuilder
来创建带有片段的 URL。
例如:
var uri = new UriBuilder(Token.Location) { Path = "/users/api/login" }.Uri;
现在您不必担心 Token.Location
是否以 /
结尾。该框架将确保它是 well-formed.
至于将 object 发布为 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());
}
}
这将序列化并将适当的 header 应用于您的请求。然后它将读回请求并将其反序列化为 object
。您希望将 object
替换为您创建的模型,以便于阅读。
我知道这个答案对于您所问的内容有些言过其实,但我想在人们第一次开始使用 HttpClient
时提供一些提示,因为有一些“陷阱”被遗漏了。
因此,对于您的答案,请使用上面的代码并将 theObjectToSend
替换为 new {}
,然后看看会发生什么。
如果仍然无法正常工作,请使用 Fiddler 之类的工具来调试您的 HTTP 调用以查看您缺少什么。
我有这个 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");
我不断收到“错误请求”,因为我发送的不是空的正文。
我已经在邮递员中尝试过,它适用于 {}
的空原始主体。我在这里错过了什么?
您要做的第一件事是确保您使用的是 shared HttpClient. If you are in ASP.NET Core, use IHttpClientFactory
. You can learn why here。
既然你要分享你的HttpClient
,最好不要使用DefaultReqestHeaders
,因为它会影响所有请求,header 字典不是 thread-safe。因此,如果一个线程正在修改 collection,同时另一个线程正在修改,您将崩溃。
这并不是说您应该永远使用DefaultRequestHeaders
。如果您不想一遍又一遍地设置相同的 header,它们会很方便。您设置一次该值,所有请求都共享该值。
考虑到这一点,使用 SendAsync
总是好的。此方法采用 HttpRequestMessasage
,它允许您将 header 隔离到那个请求。
一个典型的使用场景是:
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();
}
}
这将向 https://www.example.com
发送 GET 请求,其中 Authorization
header 的值为 token
.
HttpRequestMessage
有自己的一组 header 与 DefaultRequestHeaders
结合使用。
接下来要考虑的事情,这超出了您的问题范围,但值得提出:尝试使用 UriBuilder
来创建带有片段的 URL。
例如:
var uri = new UriBuilder(Token.Location) { Path = "/users/api/login" }.Uri;
现在您不必担心 Token.Location
是否以 /
结尾。该框架将确保它是 well-formed.
至于将 object 发布为 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());
}
}
这将序列化并将适当的 header 应用于您的请求。然后它将读回请求并将其反序列化为 object
。您希望将 object
替换为您创建的模型,以便于阅读。
我知道这个答案对于您所问的内容有些言过其实,但我想在人们第一次开始使用 HttpClient
时提供一些提示,因为有一些“陷阱”被遗漏了。
因此,对于您的答案,请使用上面的代码并将 theObjectToSend
替换为 new {}
,然后看看会发生什么。
如果仍然无法正常工作,请使用 Fiddler 之类的工具来调试您的 HTTP 调用以查看您缺少什么。