может использовать API GET, но не API POST

Im работает над существующим проектом Windows Service в VS 2013.

Я добавил класс API-интерфейса API, который я не могу запомнить, если его класс (v2.1) или (v1) контроллера... В любом случае я назвал его SyncPersonnelViaAwsApiController

Я пытаюсь называть его из лямбда AWS... так что если я позвоню GET

public string Get(int id)
    {
        return "value";
    }

с константой req = https.request(' https://actualUrlAddress/api/SyncPersonnelViaAwsApi/Get/4 ', (res) => {

Я получаю returned body: undefined"value" которое является правильным. Однако, если я попробую позвонить

const req = https.request('https://actualUrlAddress/api/SyncPersonnelViaAwsApi/SapCall', (res) => {

Я returned body: undefined{"Message":"The requested resource does not support http method 'GET'."}

 //// POST api/<controller>
    public string SapCall([FromBody]string xmlFile)
    {
        string responseMsg = "Failed Import User";

        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 \"}";
    }

Кто-нибудь знает, почему он работает для GET, а не POST?

Поскольку мы можем поразить уверенность, что это не лямбда, но я включил его просто в

const AWS = require('aws-sdk');
const https = require('https');
var s3 = new AWS.S3();
var un;
var pw;
var seralizedXmlFile;


let index = function index(event, context, callback) {

    // For the purpose of testing I have populated the bucket and key params with objects that already exist in the S3 bucket  
    var params = {
    Bucket: "testbucketthur7thdec",
    Key: "personnelData_50312474_636403151354943757.xml"
};


// Get Object from S3 bucket and add to 'seralizedXmlFile'
s3.getObject(params, function (data, err) {
    console.log("get object from S3 bucket");
    if (err) {
        // an error occurred
    }
    else
    {
        console.log("data " + data);
        // populate seralizedXmlFile with data from S3 bucket
        let seralizedXmlFile = err.Body.toString('utf-8'); // Use the encoding necessary
        console.log("objectData " + seralizedXmlFile);
    }

});

    // set params
    var ssm = new AWS.SSM({ region: 'Usa2' });
    console.log('Instatiated SSM');
    var paramsx = {
        'Names': ['/Sap/ServiceUsername', '/Sap/ServicePassword'],
        'WithDecryption': true
    };

// password and username
    ssm.getParameters(paramsx, function (err, data) {
        console.log('Getting parameter');
        if (err) console.log(err, err.stack); // an error occurred
        else {
            console.log('data: ' + JSON.stringify(data));           // successful response
            console.log('password: ' + data.Parameters[0].Value);
            console.log('username: ' + data.Parameters[1].Value);
            pw = data.Parameters[0].Value;
            un = data.Parameters[1].Value;
        }


        // request to external api application & remove dependency on ssl
        process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

        //POST DOES NOT WORK
        const req = https.request('https://actualUrlAddress/api/SyncPersonnelViaAwsApi/SapEaiCall', (res) => {
        //GET WORKS
       // const req = https.request('https://actualUrlAddress/api/SyncPersonnelViaAwsApi/Get/4', (res) => {

            res.headers + 'Authorization: Basic ' + un + ':' + pw;
            let body = seralizedXmlFile;
            console.log('seralizedXmlFile: ' + seralizedXmlFile); 
            console.log('Status:', res.statusCode);
            console.log('Headers:', JSON.stringify(res.headers));

            res.setEncoding('utf8');
            res.on('data', (chunk) => body += chunk);
            res.on('end', () => {
                console.log('Successfully processed HTTPS response');
                callback(null, body);
                console.log('returned body:', body);

            });
        });
        req.end();
    });
};
exports.handler = index;

ОБНОВЛЕНИЕ Спасибо @Thangadurai сообщение с AWS Lambda - NodeJS POST запрос и асинхронный файл записи/чтения

Я смог включить post_options... см. Обновленную лямбду

          // An object of options to indicate where to post to
    var post_options = {
        host: 'https://actualUrlAddress',
        port: '80',
        path: '/api/SyncPersonnelViaAwsApi/SapEaiCall',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': post_data.length
        }
    };

 const req = https.request(post_options, (res) => {
   res.headers + 'Authorization: Basic ' + un + ':' + pw;
            let body = seralizedXmlFile;
            console.log('seralizedXmlFile: ' + seralizedXmlFile); 
            console.log('Status:', res.statusCode);
            console.log('Headers:', JSON.stringify(res.headers));

            res.setEncoding('utf8');
            res.on('data', (chunk) => body += chunk);
            res.on('end', () => {
                console.log('Successfully processed HTTPS response');
                callback(null, body);
                console.log('returned body:', body);

            });
        });
        req.end();

Теперь он помечен как ошибка:

Error: getaddrinfo ENOTFOUND http://actualUrlAddress http://actualUrlAddress.private:80

Раньше у меня была эта ошибка getaggrinfo ENOTFOUND, это означает, что она не может найти адрес.... но arnt имя хоста и путь api правильно?

Я пытаюсь достичь

const req = https.request('https://actualUrlAddress/api/SyncPersonnelViaAwsApi/SapCall

и да, порт 80

любая помощь будет оценена Та М

Ответы

Ответ 1

Переход к части обновления (все остальное не имеет значения, как я понимаю). Параметры должны выглядеть так:

var post_options = {
    host: 'actualUrlAddress',
    protocol: 'https:'
    port: '443',
    path: '/api/SyncPersonnelViaAwsApi/SapEaiCall',
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Content-Length': post_data.length
    }
};

Поскольку, как указано в документации, хост и протокол находятся в двух отдельных свойствах, а для SSL-порта маловероятно 80, обычно это 443.

Ответ 2

Учитывая, что веб-API используется, предполагается, что маршрут по умолчанию также настроен.

Я бы предложил включить маршрутизацию атрибутов

Маршрутизация ссылочной атрибутики в ASP.NET Web API 2

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        // Attribute routing.
        config.MapHttpAttributeRoutes();

        // Convention-based routing.
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

и обновление контроллера с соответствующими атрибутами и синтаксисом

[RoutePrefix("api/SyncPersonnelViaAwsApi")]
public class SyncPersonnelViaAwsApiController : ApiController {

    //GET api/SyncPersonnelViaAwsApi/4
    [HttpGet]
    [Route("{id:int}")]
    public IHttpActionResult Get(int id) {
        return Ok("value");
    }

    //POST api/SyncPersonnelViaAwsApi
    [HttpPost]
    [Route("")]
    public IHttpActionResult SapCall([FromBody]string xmlFile) {
        string responseMsg = "Failed Import User";

        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";
            }
        }

        var data = new { 
            response = responseMsg,
            isNewActiveDirectoryUser = false
        };

        Ok(data);
    }
}

Обратите внимание на ожидаемые пути в комментариях выше действий.

Атрибуты [Http{Verb}] определяют структуру маршрутизации, какие запросы могут быть сопоставлены с действием.

теперь от клиента пути для вызова будут

GET api/SyncPersonnelViaAwsApi/4
POST api/SyncPersonnelViaAwsApi

Как уже упоминалось в комментариях, порт 80 не используется для HTTP-вызовов. Даже связанный пример в обновленном вопросе использует порт 443 для вызовов HTTPS. Заголовок в параметрах показывает JSON, но body указывает, что отправляется XML.

var post_options = {
    host: 'actualUrlAddress',
    protocol: 'https',
    port: '443',
    path: '/api/SyncPersonnelViaAwsApi',
    method: 'POST',
    headers: {
        'Content-Type': 'application/xml',
        'Content-Length': post_data.length
    }
};

Чтобы клиент мог успешно взаимодействовать с веб-API, клиенту необходимо убедиться, что он делает действительный запрос.