RestSharp 在 POST 上默认 Content-Type 为 application/x-www-form-urlencoded

RestSharp defaulting Content-Type to application/x-www-form-urlencoded on POST

RestSharp 似乎不允许我为 post 请求覆盖 ​​Content-Type。我已按照 here 中的说明进行操作,但无济于事。我还尝试通过 request.AddHeaders("content-type", "application/json");

手动将 header 内容类型设置为 application/json

请求执行示例:

private IRestResponse ExecuteRequest<T>(string resource, Method method, T model)
{
    var client = CreateRestClient();
    var request = new RestRequest(resource, method) 
    { 
        RequestFormat = DataFormat.Json 
    };
    var json = JsonConvert.SerializeObject(model);

    request.AddHeader("Accept", "application/json");
    request.AddHeader("User-Agent", "Fiddler");
    request.Parameters.Clear();
    request.AddParameter("auth_token", _apiKey);
    request.AddParameter("application/json", json, ParameteType.RequestBody);

    return client.Execute(request); 
}

响应错误信息:

{
  "error": {
  "code": 400,
  "message": "The request requires a properly encoded body with the 'content-type' header set to '['application/json']",
  "type": "Bad Request" }
}

Fiddler请求原始数据:

POST  **omitted** HTTP/1.1
Accept: application/json, application/xml, text/json, text/x-json,text/javascript, text/xml
User-Agent: RestSharp/105.0.1.0
Content-Type: application/x-www-form-urlencoded
Host: **omitted**
Content-Length: 51
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

如您所见,请求 Content-Type 仍然是 application/x-www-form-urlencoded。有任何想法吗? (提前致谢)

这似乎是对 RestSharp 如何解释 post 请求参数的误解。来自 John Sheehan 在 google 组的 post:

If it's a GET request, you can't have a request body and AddParameter adds values to the URL querystring. If it's a POST you can't include a POST parameter and a serialized request body since they occupy the same space. You could do a multipart POST body but this is not very common. Unfortunately if you're making a POST the only way to set the URL querystring value is through either string concatenation or UrlSegments:

var key = "12345";
var request = new RestRequest("api?key=" + key);
// or
var request = new RestRequest("api?key={key});
request.AddUrlSegment("key", "12345");

我现在可以使用的修改后的执行请求方法如下所示:

private IRestResponse ExecuteRequestAsPost<T>(T model, string resource, Method method)
{
    resource += "?auth_token={token}";
    var client = CreateRestClient();
    var request = new RestRequest(resource, method) { RequestFormat = DataFormat.Json };
    var json = JsonConvert.SerializeObject(model);
    request.AddHeader("User-Agent", "Fiddler");

    request.AddUrlSegment("token", _apiKey);
    request.AddParameter("application/json", json, ParameterType.RequestBody);

    return client.Execute(request);
}

听起来您可能已经想通了,但如果您对替代方案感兴趣,我写作 Flurl 的目标之一是更明确地说明您要放置参数的位置,但是仍然用更少的代码来做。在这种情况下,整个请求看起来像这样:

var response = await baseUrl
    .AppendPathSegment(resource)
    .SetQueryParam("auth_token", _apiKey)
    .WithHeader("User-Agent", "Fiddler")
    .PostJsonAsync(model);