C# HTTP Body with GET method

2019-04-08 15:05发布

问题:

I'm using an API that requires me to set the method to GET and include a message body. However when I try to do this I get the following error: "Cannot send a content-body with this verb-type". I read that the HttpWebRequest class does not support this and is the reason for the exception. Is there a work around?

This is my current code: data is a json string encoded as a byte array

HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
request.ContentType = "application/json";
request.ContentLength = data.Length;
using (Stream requestStream = request.GetRequestStream()) {
    requestStream.Write(data.ToArray(), 0, (int)data.Length);
}

This is the PHP code I'm trying to emulate

<?php
$data = array("id" => "1234");
$data_string = json_encode($data);
$ch = curl_init('url');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
var_dump($result);
?>

Thank you,

回答1:

What does one call an API that actively goes against REST? "HASTE"? "DISQUIET"?

With a bit of luck they service just doesn't care what the verb is and the PHP code was just happening to use GET and hit the bug that the server didn't block it which is a pretty minor bug as long as it behaves correctly, and it'll be fine with POST.

Failing that, your best bet is to see if they have an alternative method that either (if it's a reading request that naturally fits GET) accepts parameters in the URI with perhaps appropriate headers being used as per RFC 2616, or else can accept something through POST, GET etc.

If that doesn't work, you'll have to build an HTTP client on top of TcpClient. Which would be pretty horrible.



回答2:

This is possible, but with two caveats:

  • You must be using .NET Core (any version) - the Framework does not support this
  • You must use the HttpClient class - the older HttpWebRequest and friends won't work

Here's an example:

// be careful of disposing this client if you intend to make many requests
// - see https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
using (var client = new HttpClient())
{
    var request = new HttpRequestMessage
    {
        RequestUri = new Uri("some url"),
        Method = HttpMethod.Get,
    };

    request.Content = new ByteArrayContent(Encoding.UTF8.GetBytes("some json"));

    request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

    var result = client.SendAsync(request).Result;
    result.EnsureSuccessStatusCode();

    var responseBody = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
}


回答3:

It is not recommended to send content with a GET request. See this post for further details: HTTP GET with request body

And this is what Roy Fielding has to say about the topic.



标签: c# .net http