Reputation: 1229
I need to send a GET request to a service that expects JSON in the request body. I understand that GET requests are not meant to be used this way, but I have no control over the service and need to use the existing API, however broken it may be.
So, here's what doesn't work:
var req = (HttpWebRequest)WebRequest.Create("localhost:3456");
req.ContentType = "application/json";
req.Method = "GET";
using (var w = new StreamWriter(req.GetRequestStream()))
w.Write(JsonConvert.SerializeObject(new { a = 1 }));
It fails with:
Unhandled Exception: System.Net.ProtocolViolationException: Cannot send a content-body with this verb-type.
at System.Net.HttpWebRequest.CheckProtocol(Boolean onRequestStream)
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
at System.Net.HttpWebRequest.GetRequestStream()
Makes sense. How do I bypass this?
Thanks!
Upvotes: 0
Views: 294
Reputation: 1229
It seems the only way to do this is to fall down to using TcpClient directly, so that's what I've done. Here's some example source code that works for me:
using (var client = new TcpClient(host, port))
{
var message =
$"GET {path} HTTP/1.1\r\n" +
$"HOST: {host}:{port}\r\n" +
"content-type: application/json\r\n" +
$"content-length: {json.Length}\r\n\r\n{json}";
using (var network = client.GetStream())
{
var data = Encoding.ASCII.GetBytes(message);
network.Write(data, 0, data.Length);
using (var memory = new MemoryStream())
{
const int size = 1024;
var buf = new byte[size];
int read;
do
{
read = network.Read(buf, 0, buf.Length);
memory.Write(buf, 0, read);
} while (read == size && network.DataAvailable);
// Note: this assumes the response body is UTF-8 encoded.
var resp = Encoding.UTF8.GetString(memory.ToArray(), 0, (int) memory.Length);
return resp.Substring(resp.IndexOf("\r\n\r\n", StringComparison.Ordinal) + 4);
}
}
}
Upvotes: 1