【发布时间】:2017-09-08 06:21:36
【问题描述】:
我正在努力使用一个 API 端点 (http://ogre.adc4gis.com/convertJson),它接受 JSON 数据并返回一个 zip 文件。访问http://ogre.adc4gis.com 会显示 api 期望的参数。
它绝对可以使用 Postman 和 Javascript,所以我想知道我在 c# 代码中做错了什么。
这是一个示例 JSON 字符串,可以发布到 API:
{
"displayFieldName": "NUM_GES2_1",
"fieldAliases": {
"NUM_GES2_1": "NUM_GES2_1"
},
"geometryType": "esriGeometryPoint",
"spatialReference": {
"wkid": 102362,
"latestWkid": 4647
},
"fields": [{
"name": "NUM_GES2_1",
"type": "esriFieldTypeString",
"alias": "NUM_GES2_1",
"length": 254
}],
"features": [{
"attributes": {
"NUM_GES2_1": "001-08"
},
"geometry": {
"x": 32674408.2009,
"y": 5790291.4659000002
}
}]
}
为了完整起见,这是调用定制 api 的操作方法:
[HttpGet]
[Route("{id:int}/Attributive")]
public async Task<IActionResult> GetFeatureClass(int id)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//get token from internal api
var token = await _tokenService.RefreshToken();
//dummy address that returns a single object for development
var tokenObjString = await client.GetStringAsync(
$"http://url.to/MapServer/{id}/query?where=1%3D1&objectIds=4&f=pjson&token={token}"
);
var data = await PostDataToOgrService(tokenObjString);
var response = File(data, "application/octet-stream", "FeatureClass.Zip");
return response;
}
这里是对 api 进行实际调用的部分。 Payload 是转义的 json 字符串。摆脱所有的转义,我刚刚将它转换为一个对象,然后再返回。
public async Task<byte[]> PostDataToOgrService(string payload)
{
var client = new HttpClient();
var newJson = JsonConvert.DeserializeObject(payload);
var pairs = new Dictionary<string, object>
{
{ "json", newJson }
};
var json = JsonConvert.SerializeObject(pairs);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("http://ogre.adc4gis.com/convertJson", content);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsByteArrayAsync();
}
else
{
throw new Exception("Something went wrong");
}
}
每次调用都会返回错误 400 错误请求:
{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.NoWriteNoSeekStreamContent, Headers:
{
Date: Fri, 08 Sep 2017 06:15:01 GMT
ETag: W/"27-Ag3Jnk3T/v6dECAccJTzg4aO/wA"
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Expose-Headers: Content-Disposition
Content-Length: 39
Content-Type: application/json; charset=utf-8
}}
我尝试过的事情:
不要将有效负载转换为对象,直接使用它:
var pairs = new Dictionary<string, string>
{
{ "json", payload }
};
var json = JsonConvert.SerializeObject(pairs);
var content = new StringContent(json, Encoding.UTF8, "application/json");
构建原始字符串内容:
payload = "{ \"json\": " + payload + "}";
使用“application/x-www-url-formencoded”作为Content-Type
我在这里完全失去了。我做错了什么?
编辑 根据要求,以下是来自成功邮递员请求的请求标头:
POST /convertJson HTTP/1.1
cache-control: no-cache
Postman-Token: 2976abca-6725-43ce-873e-907c12a9fdee
Content-Type: multipart/form-data; boundary=--------------------------829328978588990941765750
User-Agent: PostmanRuntime/6.1.6
Accept: */*
Host: ogre.adc4gis.com
accept-encoding: gzip, deflate
content-length: 629
Connection: keep-alive
【问题讨论】:
-
在从 Postman 发出请求时发送的标头值是什么?当我通过 Postman 将上述 JSON 发送到端点时,我收到
Bad Request错误。什么是var token = await _tokenService.RefreshToken();。它是强制性的吗?File(data, "application/octet-stream", "FeatureClass.Zip");你的意图是什么 -
请求标头已更新。忽略令牌服务。它仅用于生成 authtoken 以首先获取 Json。这就是为什么我提供了一个示例 Json 字符串。
-
使用 Telerik fiddler 或类似工具观察线路上的消息,并将 postman 与 c# outbound 进行比较。请特别注意标题。
标签: c# json post asp.net-core httpclient