Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call HTTP GET with JSON body content parameters

Tags:

c#

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."

like image 930
Donald Avatar asked Jan 23 '19 03:01

Donald


People also ask

Can you use JSON body with GET request?

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.

CAN GET request have body parameters?

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.

Can you send a payload with a GET request?

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.


2 Answers

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.

like image 95
alfoks Avatar answered Oct 12 '22 06:10

alfoks


It is entirely possible, but you have to use the newer HttpClient class: https://stackoverflow.com/a/47902348/70345

like image 25
Ian Kemp Avatar answered Oct 12 '22 04:10

Ian Kemp