How can I call HTTP GET using JSON parameters in content body?
I tried this:
HttpWebRequest.WebRequest.Create(_uri);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "GET";
httpWebRequest.Headers.Add("X-AUTH-TOKEN", _apiKey);
using(var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) {
string _json = "\"{\"filter\": {\"relation\": \"equals\", \"attribute\": \"state\", \"value\": \"CA\" }, \"insights\": {\"field\": \"family.behaviors\", \"calculations\": [\"fill_count\"]}}";
streamWriter.Write(_json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
using(var streamReader = new StreamReader(httpResponse.GetResponseStream())) {
var result = streamReader.ReadToEnd();
}
but it throws an exception:
"Cannot send a content-body with this verb-type."
Not only does the HTTP spec allow body data with GET request, but this is also common practice: The popular ElasticSearch engine's _search API recommends GET requests with the query attached in a JSON body. As a concession to incomplete HTTP client implementations, it also allows POST requests here.
GET requests don't have a request body, so all parameters must appear in the URL or in a header. While the HTTP standard doesn't define a limit for how long URLs or headers can be, mostHTTP clients and servers have a practical limit somewhere between 2 kB and 8 kB.
Note: Sending body/payload in a GET request may cause some existing implementations to reject the request — while not prohibited by the specification, the semantics are undefined. It is better to just avoid sending payloads in GET requests.
If you use .NET core, the new HttpClient
can handle this. Otherwise you can use System.Net.Http.WinHttpHandler package, but it has a ton of dependencies. See answer
https://stackoverflow.com/a/47902348/1030010
for how to use these two.
I can't use .NET core and I don't want to install System.Net.Http.WinHttpHandler
.
I solved it by using reflection, to trick WebRequest
that it is legal to send body with a GET request (which is according to latest RFC). What I do is to set ContentBodyNotAllowed
to false for HTTP verb "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();
Note, however, that the attribute ContentBodyNotAllowed
belongs to a static field, so when its value changes, it remains in effect for the rest of the program. That's not a problem for my purposes.
It is entirely possible, but you have to use the newer HttpClient
class: https://stackoverflow.com/a/47902348/70345
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With