GET 请求适用于 HttpWebRequest,Postman 。但不在 HttpClient 或 RestSharp 中

Posted

技术标签:

【中文标题】GET 请求适用于 HttpWebRequest,Postman 。但不在 HttpClient 或 RestSharp 中【英文标题】:GET request works in HttpWebRequest,Postman . but not in HttpClient or RestSharp 【发布时间】:2018-04-22 15:53:36 【问题描述】:

以下是我的要求

GET /api/v3/countries HTTP/1.1
Host: api-sandbox.grnconnect.com
Content-Type: application/json
Accept: application/json
api-key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX

我在 postman 中尝试过,它正在工作。 此外,它还可以使用 HttpWebRequest 与以下代码一起使用。

var httpWebRequest = (HttpWebRequest) WebRequest.Create(url);
httpWebRequest.Headers.Clear();
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "GET";
httpWebRequest.Headers.Add("api-key", "XXXXXXXXXXXXXXXXXXX");
httpWebRequest.Accept = "application/json";
string result = ""

using(HttpWebResponse response = httpWebRequest.GetResponse() as HttpWebResponse) 
    if (response.StatusCode != HttpStatusCode.OK) throw new Exception(String.Format("Server error (HTTP 0: 1).", response.StatusCode, response.StatusDescription));
    Stream stream1 = response.GetResponseStream();
    StreamReader sr = new StreamReader(stream1);
    result = sr.ReadToEnd();

return result;

但是当我尝试使用 httpclient 时,它会以 Code 400 响应,“不支持的媒体类型”。 以下是代码。

string response = "";
using(var httpClient = new HttpClient()) 
httpClient.DefaultRequestHeaders.Clear();
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("ContentType", "application/json; charset=utf-8");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("api-key", "XXXXXXXXXXXXXXXXXXXXX");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "application/json");

response = httpClient.GetAsync(url).Result.
Content.
ReadAsStringAsync().Result;

return response;

还有 HttpClient.SendAsync

string response = "";
using(var httpClient = new HttpClient()) 
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url);
requestMessage.Headers.Add("Accept", "application/json");
requestMessage.Headers.Add("ContentType", "application/json");
requestMessage.Headers.Add("api-key", "XXXXXXXXXXXXXXXXXXXXXXXX");
response = httpClient.SendAsync(requestMessage)
.Result.Content.ReadAsStringAsync().Result;

return response;

使用 Microsoft Network Monitor 分析网络流量。 两者看起来一样

网络请求

- Tcp: Flags=...AP..., SrcPort=5403, DstPort=HTTP(80), PayloadLen=193, 
Seq=1190693031 - 1190693224, Ack=2045565534, Win=68 (scale factor 0x8) = 17408
....
....
- Http: Request, GET /api/v3/countries 
Command: GET
- URI: /api/v3/countries
 Location: /api/v3/countries 
ProtocolVersion: HTTP/1.1
- ContentType:  application/json
 MediaType:  application/json
api-key:  XXXXXXXXXXXXXXXXXX
Accept:  application/json
Host:  api-sandbox.grnconnect.com
Connection:  Keep-Alive
HeaderEnd: CRLF

HttpClient

- Tcp: Flags=...AP..., SrcPort=5390, DstPort=HTTP(80), PayloadLen=192, 
Seq=3916100376 - 3916100568, Ack=2674317805, Win=256 (scale factor 0x8) = 
65536
.....
.....
- Http: Request, GET /api/v3/countries 
Command: GET
- URI: /api/v3/countries
 Location: /api/v3/countries 
ProtocolVersion: HTTP/1.1
- ContentType:  application/json
 MediaType:  application/json
api-key:  XXXXXXXXXXXXXXXXXXXXXX
Accept:  application/json
Host:  api-sandbox.grnconnect.com
Connection:  Keep-Alive
HeaderEnd: CRLF

唯一不同的是 PayloadLen

如何解决?

我也尝试过使用 Restharp 代码。但还是一样的 400 错误

var client = new RestClient("http://api- 
sandbox.grnconnect.com/api/v3/countries");
var request = new RestRequest(Method.GET);
request.AddHeader("api-key", "XXXXXXXXXXXXXX");
request.AddHeader("accept", "application/json");
request.AddHeader("content-type", "application/json");
IRestResponse response = client.Execute(request);

【问题讨论】:

您是否应该在 HttpClient 的第一个 GET 请求中使用Accept: application/json; charset=utf-8?而且什么也没发? Postman 可以为你生成 Restsharp 代码。在发送和保存按钮下是“代码”。单击它,选择 RestSharp 并查看您的代码有何不同。 @john 我添加了这些,因为只有接受,ContentType 我才能在 WebRequest 中成功。即使我将它添加到 HttpClient 中,它也会以错误响应。 @Crowcoder posed code是postman生成的。 【参考方案1】:

使用 MediaType 标头值设置 httpclient

client.DefaultRequestHeaders.Accept
    .Add(new MediaTypeWithQualityHeaderValue("application/json"));

【讨论】:

以上是关于GET 请求适用于 HttpWebRequest,Postman 。但不在 HttpClient 或 RestSharp 中的主要内容,如果未能解决你的问题,请参考以下文章

HttpClient替换HttpWebRequest--以GET和POST请求为例说明

GJM : C# HttpWebRequest GET HTTP HTTPS 请求

在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求

HttpWebRequest 对每个主机 2 个连接的限制是不是适用于 HttpClient?

网络请求HttpWebRequest的Get和Post

C# HttpWebRequest GET HTTP HTTPS 请求