【问题标题】:How to make GET with request body如何使用请求正文进行 GET
【发布时间】:2019-07-30 10:20:48
【问题描述】:

如何使用RestSharp 对请求正文进行GET 查询(我正在使用带有.NET Core 2.2 的RestSharp v. 106.6.10)。我可以使用WebClient/Postman 等来做到这一点。没问题。

这里的代码失败了{["A non-empty request body is required."]}

var client = new RestClient("BaseUri");
var request = new RestRequest("URL", Method.GET);
request.AddJsonBody(Body); 
client.Execute(request); // {["A non-empty request body is required."]}

这代表了一个valid 用例,如果不支持就可惜了。

更新:使用带有正文的 GET 请求的动机是利用具有复杂参数的 get 请求,这些参数不能很好地编码为查询字符串。我知道人们将他们的 json 序列化并将它们放入查询字符串中,但我宁愿将其放入请求正文中,因为毕竟这是一种允许的用法。

【问题讨论】:

  • 这在技术上可能是允许的,但是 - 这不是完全正常的用法;有些工具不喜欢它并不让我感到惊讶;但是:你试过HttpClient吗?
  • @IvMisticos - 不起作用,出现同样的错误。
  • @MarcGravell 我已经尝试过 WebClient,但似乎也不喜欢它,明确表示 GET 不允许有正文。
  • @MarcGravell ProtocolViolationException:无法发送具有此动词类型的内容主体。是我从 WebClient 得到的。

标签: c# .net rest .net-core restsharp


【解决方案1】:

根据我的经验,AddJsonBody 完全坏了(有很多次没有序列化我的模型,只是粘贴到 Body 中,比如 MyProject.Models.MyModel 甚至让 body 为空)。所以我使用以下内容:

var client = new RestClient("BaseUri");
var request = new RestRequest("URL", Method.GET);
request.AddHeader("Content-Type", "application/json");
string serializedBody = Newtonsoft.Json.JsonConvert.SerializeObject(Body);
request.AddParameter("application/json; charset=utf-8", serializedBody, ParameterType.RequestBody);
client.Execute(request);

更新抱歉,我在阅读您的问题时没有耐心。答案是针对RestSharp 而不是PostSharp

【讨论】:

  • 试了一下,得到:“StatusCode: UnsupportedMediaType, Content-Type: , Content-Length: 0)”
  • 添加后:request.AddHeader("Content-Type", "application/json; charset=utf-8");我开始收到我原来的 BadRequest。
  • 可能您的服务器不允许在未指定 Content-Length 的情况下进行调用。尝试添加request.AddHeader("Content-Length", $"{System.Text.Encoding.ASCII.GetByteCount(serializedBody)}");
  • 不满意的不是长度,而是Content-Type。我猜 RestSharp 可以很好地使用 WebClient/HttpClient 在这种情况下它被预定义为失败。
  • RestSharp 似乎是正确的——这与 PostSharp 无关。我已建议对问题进行编辑 - 等待同行评审。
【解决方案2】:

我通过使用 reflection 解决了这个问题,以欺骗 WebRequest 发送带有 GET 请求的正文是合法的。

1.为车身参数创建模型,

public class SampleBodyModel
{
    public String name{ get; set; }
    public String password{ get; set; }
}
  1. 初始化请求。

    SampleBodyModel sampleRequest = new SampleBodyModel
    {
          name= "name",
          password= "password"
    };
    
    //initialize the API call
    var request = WebRequest.Create("API_END_POINT");
    request.ContentType = "application/json";
    request.Method = "GET";
    var myHttpWebRequest = (HttpWebRequest)request;
    
    // ------- Add these two lines if your using JWT token -------
    myHttpWebRequest.PreAuthenticate = true;
    myHttpWebRequest.Headers.Add("Authorization", "Bearer " + "TOKEN");
    // -----------------------------------------------------------
    
    var type = myHttpWebRequest.GetType();
    var currentMethod = type.GetProperty("CurrentMethod", 
            BindingFlags.NonPublic | BindingFlags.Instance).GetValue(myHttpWebRequest);
    var methodType = currentMethod.GetType();
    methodType.GetField("ContentBodyNotAllowed", BindingFlags.NonPublic | 
             BindingFlags.Instance).SetValue(currentMethod, false);
    
    //Add the Request body
    using (var streamWriter = new 
          StreamWriter(myHttpWebRequest.GetRequestStream()))
    {
    
         streamWriter.Write(Newtonsoft.Json.JsonConvert.SerializeObject(sampleRequest));
    }
    var response = (HttpWebResponse)myHttpWebRequest.GetResponse();
    var responseStream = response.GetResponseStream();
    
    var myStreamReader = new StreamReader(responseStream, Encoding.Default);
    var json = myStreamReader.ReadToEnd();
    
    responseStream.Close();
    response.Close();
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 2022-01-25
    • 2021-09-28
    • 2020-09-20
    • 1970-01-01
    相关资源
    最近更新 更多