johnstaveley
johnstaveley

Reputation: 1499

Http Post to .net isolated azure function Body Empty (most) of the time

I am executing the following:

HttpClient _httpClient= new HttpClient
{
   BaseAddress = new Uri("http://localhost:7071/api/"), // Local
   Timeout = TimeSpan.FromSeconds(60)
};
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

 var stopMessage = new Domain.StopMessage
    {
    SiteId = "SiteId",
    };

 var response = await _httpClient.PostAsJsonAsync("StopMessage", stopMessage);

Against this function:

    [Function("StopMessage")]
    public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req, FunctionContext executionContext)
    {
        var log = executionContext.GetLogger(nameof(StopMessage));
        try
        {
            DateTime currentDate = DateTime.Now;
            string requestBody = string.Empty;
            using (StreamReader streamReader = new StreamReader(req.Body))
            {
                requestBody = await streamReader.ReadToEndAsync();
            }

I am using a .net isolated function. Here is my host.json:

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "functionTimeout": "00:05:00",
  "extensions": {
    "eventHubs": {
      "batchCheckpointFrequency": 5,
      "eventProcessorOptions": {
        "maxBatchSize": 256,
        "prefetchCount": 512
      },
      "initialOffsetOptions": {
        "type": "fromEnqueuedTime",
        "enqueuedTimeUtc": "2021-11-01T00:00Z"
      }
    }
  },
  // Configuration settings for Singleton lock behavior. (Optional)
  "singleton": {
    // The period that function level locks are taken for (they will auto renew)
    "lockPeriod": "00:01:00"
  }
}

75% of the time requestBody is empty and the transfer is not made. I can repeat send the same request multiple times and sometimes it will populate the body and sometimes it won't. How can I make it that it the body is always present?

Upvotes: 0

Views: 1585

Answers (1)

Anders Urban
Anders Urban

Reputation: 33

Update September 2023

This issues is caused by _httpClient.PostAsJsonAsync("StopMessage", stopMessage); sending the underlying JSON document as chunked.

But the HttpRequestData does not support Chunked JSON and as such it returns null.

The issues have been discussed in length in this GitHub issue: https://github.com/Azure/azure-functions-host/issues/4926

The current solution is to use the ASP.NET Core Integration described here: https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide#aspnet-core-integration


Original answer April 2022

The issue seem to be between _httpClient.PostAsJsonAsync("StopMessage", stopMessage); and HttpRequestData

I can not give you the reason to why this issue occours.

But if JsonSerializer.Serialize is used it seems to work fine.

string json = JsonSerializer.Serialize(stopMessage);

var httpResponseMessage = await _httpClient.PostAsync("StopMessage", new StringContent(json));

Upvotes: 3

Related Questions