我很难使用一个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");
构建字符串内容raw:
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
答案 0 :(得分:2)
最后,我只是使用Fiddler从网站本身重建有效负载,以便首先捕获它并且它有效。
var contentString = "json=" + System.Web.HttpUtility.UrlEncode(JsonConvert.SerializeObject(newJson));
var content = new StringContent(contentString, Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await client.PostAsync("http://ogre.adc4gis.com/convertJson", content);