使用JSON正文内容参数调用HTTP GET

时间:2019-01-23 03:56:22

标签: c#

如何使用内容正文中的JSON参数调用HTTP GET?

我尝试过:

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();
}

但是会引发异常:

  

“无法发送具有这种动词类型的内容主体。”

4 个答案:

答案 0 :(得分:1)

GET仅会收到它。

如果需要指定参数,请将其包含在url中。
或者您可以通过POST或PUT发送JSON BODY。

HTTP request methods

  

HTTP定义了一组请求方法,以指示要对给定资源执行的所需操作。尽管它们也可以是名词,但这些请求方法有时也称为HTTP动词。它们每个都实现了不同的语义,但是它们的一些组共享了一些共同的功能:请求方法可以是安全的,幂等的或可缓存的。

     
      
  • 获取
      GET方法请求指定资源的表示形式。使用GET的请求应仅检索数据。
  •   
  • HEAD
      HEAD方法请求的响应与GET请求的响应相同,但没有响应主体。
  •   
  • POST
      POST方法用于将实体提交给指定的资源,通常会导致状态更改或对服务器产生副作用。
  •   
  • PUT
      PUT方法用请求有效负载替换目标资源的所有当前表示形式。
  •   

此外:

我发现了这个。进行了长时间的讨论。
HTTP GET with request body

这意味着可以使用GET发送BODY,但是在GET请求上发送有效内容正文可能会导致某些现有实现拒绝该请求(例如,路由中间的Proxy)。

请务必仔细阅读本文,因为还有很多其他要注意的地方。


顺便说一句,似乎可以使用cURL命令的-i选项将GET与正文一起发送。

Curl GET request with json parameter

答案 1 :(得分:1)

完全有可能,但是您必须使用较新的 Column1 Column2 Column3 a 1 5 8 b 2 6 9 0 3 7 10 0 4 8 11 类:https://stackoverflow.com/a/47902348/70345

答案 2 :(得分:0)

即使从技术上来说,allowed会发送带有class NewTestController extends Controller { public function nextQuestion(Request $request) { $attempted_questions = new AttemptedQuestion; $attempted_questions->user_id = Auth::id(); $attempted_questions->question_id = $request->attempted; $attempted_questions->save(); $attempted = AttemptedQuestion::where('user_id', Auth::id())->pluck('question_id'); $question = Question::whereNotIn('id', $attempted)->inRandomOrder()->first(); return $question->id; } } 请求的正文,Microsoft仍为您决定您不能这样做。

这可以在Get source code中看到:

HttpWebRequest

因此,您需要将动词更改为if (onRequestStream) { // prevent someone from getting a request stream, if the protocol verb/method doesn't support it throw new ProtocolViolationException(SR.GetString(SR.net_nouploadonget)); } Put或使用其他workaround

答案 3 :(得分:0)

如果使用.NET核心,则新的HttpClient可以处理此问题。否则,您可以使用System.Net.Http.WinHttpHandler程序包,但是它有很多依赖项。查看答案

https://stackoverflow.com/a/47902348/1030010

如何使用这两个。

我无法使用.NET Core,也不想安装System.Net.Http.WinHttpHandler。 我使用反射解决了这个问题,以欺骗WebRequest认为使用GET请求发送正文是合法的(根据最新的RFC)。我要做的是将HTTP动词“ GET”的ContentBodyNotAllowed设置为false。

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属于一个静态字段,因此当其值更改时,它对于程序的其余部分仍然有效。就我而言,这不是问题。