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