【发布时间】:2020-04-21 11:46:37
【问题描述】:
我正在编写一个 .NET 核心 web 服务(从现在开始我将把它称为“MyWs”),它应该触发另一个 web 服务的端点(从现在开始我将把它称为“OtherWs”)。使用邮递员向 OtherWs 发送请求时,一切正常。 但是,当我尝试从 MyWs 联系 OtherWs 时,我总是得到“未经授权”的响应 (401)。查看 Fiddler(我用来检查 http(s) 流量的工具)跟踪的请求,似乎 MyWs 实际上没有发送任何请求标头,即使它们在代码中进行了配置。
邮递员的配置方式可以在这个截图中看到: https://i.imgur.com/lclYoZT.png
Fiddler 中的请求可以在这里看到:https://imgur.com/pDDcgUb 和 https://imgur.com/7cgIGKw
尽管这可行,但这里有两件奇怪的事情在起作用:
- 授权标头在 Fiddler 中不可见。但是,我确信授权标头起着重要作用,因为当我将其更改为错误值时,我会收到“未授权”响应 (401)。
- 尽管我只触发了一个请求,但 Fiddler 记录了两个请求。我认为这可能与接收服务器的重定向有关。
我尝试了三种不同的方法来创建请求。
尝试 1:使用 Restsharp
public async Task<IActionResult> process()
{
var client = new RestClient("https://host.com");
var request = new RestRequest("servicename/endpoint", Method.POST);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Basic SecretToken");
request.AddParameter("text/json",
"{\"Key\":\"\",\"Order\":{\"DeliveryDate\":\"5/1/2020\",\"OrderLines\":[{\"ItemNr\":\"12345\",\"Quantity\":1,\"Description\":\"Some string\",\"QuantityPerUnit\":1}],\"Tries\":0}, \"Customernr\":\"123\"}"
, ParameterType.RequestBody);
var response = client.Execute(request);
var content = response.Content;
return Ok(content);
}
response 变量在触发此请求时具有 StatusCode Unauthorized。 Fiddler中对应的请求可以看这里:https://imgur.com/lDLLIYH
很明显,根本没有请求标头。不是授权标头,但也没有 Content-Type 标头,例如,即使上面的代码应该设置它。
尝试 2:使用HttpRequestMessage
public async Task<IActionResult> process2()
{
var relativeAddress = "https://host.com/servicename/endpoint";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, relativeAddress);
request.Headers.Add("Authorization", "Basic SecretToken");
// request.Headers.Add("Content-Type", "application/json");
request.Content = new StringContent(
"{\"Key\":\"\",\"Order\":{\"DeliveryDate\":\"5/1/2020\",\"OrderLines\":[{\"ItemNr\":\"12345\",\"Quantity\":1,\"Description\":\"Some string\",\"QuantityPerUnit\":1}],\"Tries\":0}, \"Customernr\":\"123\"}"
Encoding.UTF8,
"application/json");
request.Content.Headers.Remove("Content-Type");
request.Content.Headers.Add("Content-Type", "application/json");
var response = "";
await httpClient.SendAsync(request).ContinueWith(responseTask => {
response = responseTask.Result.Content.ToString();
Console.WriteLine("Response: {0}", responseTask.Result);
});
return Ok();
}
在这种情况下,响应还显示Unauthorized。
Fiddler 中的请求如下所示:https://imgur.com/5asmR0q
尝试 3:使用HttpWebRequest
public async Task<IActionResult> process3()
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("https://host.com/servicename/endpoint");
request.Method = "POST";
request.AllowAutoRedirect = true;
request.PreAuthenticate = true;
request.Headers.Add("Authorization", "Basic SecretToken");
request.ContentType = "application/json";
request.Accept = "application/json";
var response = request.GetResponse();
var responseStream = response.GetResponseStream();
if (response == null)
{
return null;
}
var myStreamReader = new StreamReader(responseStream, Encoding.Default);
var json = myStreamReader.ReadToEnd();
responseStream.Close();
response.Close();
return Ok();
}
在这种情况下,响应再次显示未经授权。我什至没有在这个请求中添加正文,但如果我不使用邮递员添加正文,它会抛出 500,因此证明这种方法也不起作用。
Fiddler 中的请求如下所示:https://imgur.com/cOJfwLN
值得注意的是,如果我将AllowAutoRedirect 设置为false,我会收到此错误:
WebException: The remote server returned an error: (307) Temporary Redirect.
我现在不知所措,因为似乎没有为我使用 .NET 发出的任何请求设置任何标头。谁能告诉我我做错了什么或指出我正确的方向?我有一种预感,它与接收服务器的重定向有关。
【问题讨论】:
标签: c# .net-core http-headers http-post