感谢EVK对我之前的Q(can use API GET but not API POST)的帮助,我能够解决当我可以点击GET时无法从节点中的aws lambda发出API POST请求的问题。问题不在于填充post_options。
无论如何,现在我能够成功调用帖子,但我无法填充身体。
相关文档https://nodejs.org/api/http.html#http_http_request_options_callback
如果你在下面看到我的API POST电话。
//// POST api/<controller>
public string SapEaiCall([FromBody]string xmlFile)
{
string responseMsg = "Failed Import Active Directory User";
if (string.IsNullOrEmpty(xmlFile))
{
responseMsg = "XML file is NULL";
}
if (responseMsg != "XML file is NULL")
{
xmlFile = RemoveFirstAndLastQuotes(xmlFile);
if (!IsNewestVersionOfXMLFile(xmlFile))
{
responseMsg = "Not latest version of file, update not performed";
}
else
{
Business.PersonnelReplicate personnelReplicate = BusinessLogic.SynchronisePersonnel.BuildFromDataContractXml<Business.PersonnelReplicate>(xmlFile);
bool result = Service.Personnel.SynchroniseCache(personnelReplicate);
if (result)
{
responseMsg = "Success Import Sap Cache User";
}
}
}
return "{\"response\" : \" " + responseMsg + " \" , \"isNewActiveDirectoryUser\" : \" false \"}";
}
每次我从aws lambda调用它时,它都会返回responseMsg = "XML file is NULL";
请参阅下面的示例:
var querystring = require('querystring');
var https = require('https');
var fs = require('fs');
exports.handler = function(event, context) {
const post_data = querystring.stringify({'msg': 'Hello World!'});
// An object of options to indicate where to post to
var post_options = {
host: 'URL',
protocol: 'https:',
port: '443',
path: '/api/SyncPersonnelViaAwsApi/SapEaiCall',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length
}
};
//ignores SSL
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var post_request = https.request(post_options, function(res) {
var body = "";
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
context.done(body);
});
res.on('error', function(e) {
context.fail('error:' + e.message);
});
});
// post the data
post_request.write(post_data);
post_request.end();
console.log("posted data " +post_data); //returns posted data msg=Hello%20World!
};
所以我填充了帖子数据,并尝试填充正文。仍然会返回XML file is NULL
有没有人知道为什么?
由于
答案 0 :(得分:1)
您正在正文中发送以下文字:
msg=Hello%20World!
并说明请求内容类型为:
'Content-Type': 'application/json'
你的身体代表有效的json吗?它没有。所以这是第一个问题 - 您的请求中声明的内容类型以及您发送的实际数据彼此不匹配。
然后让我们来看看:
public string SapEaiCall([FromBody]string xmlFile)
它基本上说:查看请求的主体并使用适合请求内容类型的绑定器来绑定xmlFile
参数的值。由于请求内容类型是“application / json” - binder期望body包含一个单独的json字符串,也就是说,在这种情况下,body应该是(包括引号):
"Hello World!"
所以,如果你通过了(例如通过const post_data = JSON.stringify('Hello World!');
- 它应该有效。
但是,如果您想在身体中传递更多参数,而不仅仅是xmlFile
,该怎么办?然后你需要定义一个模型,我会说即使你只有一个参数 - 最好这样做。例如:
public class SapEaiCallParameters {
public string XmlFile { get; set; }
}
// FromBody can be omitted in this case
public IHttpActionResult Post(SapEaiCallParameters parameters) {
}
然后你按照预期的方式调用它,传递json:
const model = {xmlFile: 'Hello World!'};
const post_data = JSON.stringify(model);
旁注:不要这样做:
return "{\"response\" : \" " + responseMsg + " \" , \"isNewActiveDirectoryUser\" : \" false \"}";
相反,创建另一个模型,如下所示:
public class SapEaiCallResponse {
public string Response { get; set; }
public bool IsNewActiveDirectoryUser { get; set; }
}
并将其归还:
public IHttpActionResult Post(SapEaiCallParameters parameters) {
...
return Json(new SapEaiCallResponse {
Response = responseMsg,
IsNewActiveDirectoryUser = false,
});
}