目前,为了向一个API接口发送一个参数化的GET请求,我写了以下代码。
api/master/city/filter?cityid=1&citycode='ny'
但我看到URL的长度有限制,为2,083个字符。
为了避免这种情况,我想在GET请求的内容体中以json格式发送参数。
然而,我看到HttpClient的Get方法都不允许发送内容体。对于POST,我看到HttpClient中有一个名为PostAsync的方法允许发送内容体。
有没有一种方法可以为GET请求发送不在URL中的参数,以避免URL长度的限制?
请阅读本答案最后的注意事项,为什么一般不建议使用带body的HTTP GET请求。
如果你使用的是.NET 核心技术,标准 HttpClient
可以做到这一点。例如,发送一个带有JSON体的GET请求。
HttpClient client = ...
...
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("some url"),
Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
.NET 架構 不支持这个开箱即用的功能(你会收到一个 ProtocolViolationException
如果你尝试上述代码)。) 值得庆幸的是,微软已经提供了 System.Net.Http.WinHttpHandler。 包,该 是否 支持该功能--只需安装并使用它来代替默认的 HttpClientHandler
在构建您的 HttpClient
实例。
var handler = new WinHttpHandler();
var client = new HttpClient(handler);
<rest of code as above>
参考文献。https:/github.comdotnetcorefxissues28135#issuecomment-467261945。
需要注意的是,带body的HTTP GET是一种非常规的结构,属于HTTP规范的灰色地带。
我不能使用.NET core,而且我不想安装。System.Net.Http.WinHttpHandler
我通过使用反射解决了这个问题,以骗取 WebRequest
在GET请求中发送body是合法的(根据最新的RFC)。我所做的是设置 ContentBodyNotAllowed
为false,用于HTTP动词 "GET"。
var request = WebRequest.Create(requestUri);
request.ContentType = "application/json";
request.Method = "GET";
var type = request.GetType();
var currentMethod = type.GetProperty("CurrentMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(request);
var methodType = currentMethod.GetType();
methodType.GetField("ContentBodyNotAllowed", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(currentMethod, false);
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write("<Json string here>");
}
var response = (HttpWebResponse)request.GetResponse();
但是,请注意,属性 ContentBodyNotAllowed
属于一个静态字段,所以当它的值发生变化时,它在程序的其余部分仍然有效。这对我的目的来说不是问题。
类似于上面的答案,但代码较少
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = targetUri,
Content = new StringContent(payload.Payload),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
var responseInfo = await response.Content.ReadAsStringAsync();