Home > OS >  .NET Core Web API only gets JSON from the Mock Lambda Tool. Using Postman, Swagger & AWS Lambda fail
.NET Core Web API only gets JSON from the Mock Lambda Tool. Using Postman, Swagger & AWS Lambda fail

Time:08-11

I recently wrote a .NET Core Web API to receive JSON from a Lambda SNS message event. The Lambda sends the SNS event message JSON (via a POST request) to the API.

When I use the 'Mock Lambda Tool' to send the SNS message to the API, all is well. It works great. The data arrives, my API's controller sees it and it sends it over to the class that parses the data sends it into a database.

So, I then published the API to IIS and tested it from the Mock Lambda Tool. That worked too.

Feeling good about the work I uploaded the Lambda to AWS (for real world scenarios), I did a quick test of the same SNS message (JSON) using the AWS Lambda console. It times out.

So, I decided to go back and try testing the API on IIS using Postman. It shows:

**POST** https://my.company.com/api/Transaction/
**201**
2.69 s
POST /api/Transaction/ HTTP/1.1
Content-Type: application/json
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Cache-Control: no-cache
Postman-Token: 4173d96a-1583-4c64-82b1-f67acaf8f0c7
Host: my.company.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 4274

*(I'm omitting the HUGE json message area. It's standard format.)*

**HEADER INFO**
HTTP/1.1 201 Created
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Location: https://my.company.com/api/Transaction/
Server: Microsoft-IIS/10.0
Date: Wed, 10 Aug 2022 01:04:41 GMT

**RESPONSE BODY**
{"Id":0,"email":null,"token":null,"storeNumber":null,"transactionDateTime":"0001-01-01T00:00:00","transactionId":null,"orderData":null}

There is NO error, but note that the Response Body is all nulls.

I decided to run the API from Visual Studio so that I could step through the code as the SNS message arrives from the Lambda.

  • Using the Mock Lambda Tool, no errors. Data goes all the way through.
  • Using Postman, a breakpoint on the controller shows no Transaction data arriving (NULL).
  • Using Swagger, a breakpoint on the controller shows no Transaction data arriving (NULL).

Are there any ideas as to what I am missing or doing incorrectly?

This is my controller in the API:

using Microsoft.AspNetCore.Mvc;
using MyWebAPI.TransactionData;
using MyWebAPI.Models;

namespace MyWebAPI.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class TransactionController : ControllerBase
    {
        private readonly ITransactionData _transactionData;

        public TransactionController(ITransactionData transactionData)
        {
            _transactionData = transactionData;
        }

        [HttpGet]
        public string Get()
        {
            return "You have reached the .NET Core Web API (web service).";
        }

        [HttpPost]
        public IActionResult DataTranslation(Transaction transactionData)
        {
            _transactionData.DataTranslation(transactionData); // entry point

            return Created(
                HttpContext.Request.Scheme
                  "://"   HttpContext.Request.Host
                  ""   HttpContext.Request.Path
                  "/"   transactionData.transactionId, transactionData
                );
        }
    }
}

Here is my POST request in the Lambda:

public void PostRequest(string msg)
{
    var url = "https://my.company.com/api/Transaction/"; // IIS
    var httpRequest = (HttpWebRequest)WebRequest.Create(url);
    httpRequest.Method = "POST";
    httpRequest.Accept = "application/json";
    httpRequest.ContentType = "application/json";

    var data = msg;

    try
    {
        // Write request data to stream
        using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream()))
        {
            streamWriter.Write(data);
        }

        // Get a response from IIS (REST API)
        var httpResponse = (HttpWebResponse)httpRequest.GetResponse();

        // Read the body of the response from the server
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            var result = streamReader.ReadToEnd();
        }                

        // Log the status code
        Log.Logger.Information(@"httpResponse: "   httpResponse.StatusCode);
    }

    catch (WebException wex)
    {
        Log.Logger.Information($"[ERROR] WebException, {wex}");
        Log.Logger.Information($"[ERROR] WebException Message, {wex.Message}");
        Log.Logger.Information($"[ERROR] WebException Response, {wex.Response}");
        Log.Logger.Information($"[ERROR] WebException Response, {wex.Response.Headers}");
        Log.Logger.Information($"[ERROR] WebException Response, {wex.Response.ResponseUri}");

        string pageContent = new StreamReader(wex.Response.GetResponseStream()).ReadToEnd().ToString();
        Log.Logger.Information($"[ERROR] pageContent, {pageContent}");
    }
    catch (Exception ex)
    {
        Log.Logger.Information($"[ERROR] Exception, {ex}");
    }

    return;
}

I'm curious if it's my Post Request that is the problem?

Why is the 'Mock Lambda Tool' the only way I can get the data over to the API?

Thanks

CodePudding user response:

Is it because you are sending the JSON in the request body vs querystring? Try using

 [HttpPost]
 public IActionResult DataTranslation([FromBody] Transaction transactionData)
 {

https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api#using-frombody message using

CodePudding user response:

UPDATE. I learned that the Lambda at AWS required a VPC to my internal VM that hosts the API on IIS. That solves why the Lambda at AWS timed out repeatedly.

As for Postman and Swagger problem, the issue is that the Mock Lambda Tool sends the entire SNS message event in its natural full format, then the Lambda extracts the Message portion only to send over to the API.

I was sending this entire SNS message event across Swagger and Postman both of which DO NOT do the work that the Lambda does which is strip just the Message portion out of the SNS event.

Once I sent only the Message portion across with Swagger and Postman, both worked.

I must give credit to my work buddy Dorian for helping me with this. Thanks! :)

  • Related