Open myarotskaya opened 4 years ago
Another workaround @fabiocav mentioned: set FUNCTIONS_V2_COMPATIBILITY_MODE
to true
in the App Settings.
Hello @pragnagopa, could you please confirm that it's a valid issue and if so, is it planned to be fixed on the Azure Functions side? Is there any ETA?
Hi. Working on a customer project and upgraded to version 3.1. I can verify that this is still an issue that needs to be resolved. Setting FUNCTIONS_V2_COMPATIBILITY_MODE to true works as a workaround though.
Please continue using FUNCTIONS_V2_COMPATIBILITY_MODE. We will update this issue with further details. No ETA yet.
Any word on this? Upgrading to v3 broke our microservices.
Having this issue and setting FUNCTIONS_V2_COMPATIBILITY_MODE does not help for me. Runs fine locally but nothing works when deployed to Azure. Am I missing something?
FUNCTIONS_V2_COMPATIBILITY_MODE is not doing the trick for me. You guys need to put a GIANT warning on the functions overview about this. I wasted so much time going in circles about this because I was not aware of this known issue. I am sure others have wasted time too. It is good to be more transparent about non obvious bugs like this.
Found another work around for others. In my case I was using GET on the function. If you use POST instead the body will come in correctly. I am not using the FUNCTIONS_V2_COMPATIBILITY_MODE.
Problem still exist when I am using: Azure Functions Core Tools (3.0.2798 Commit hash: d9d99872a51c04b1c2783198b1ee1104da6b064f)
but after I tried it couple times, the issue suddenly disappear ... and get_json() returns json data ... this is really strange
if u are using postman:
Any update on this issue? Setting FUNCTIONS_V2_COMPATIBILITY_MODE to true does not work. What is frustrating is that it works when invoked from the Test/Run form in the portal, but does not work via Postman.
I was able to repro this with @myarotskaya's repo. Looks like the problem has to do with model binding reading the body stream. By the time the function executes, there's nothing left to read. @fabiocav @pragnagopa Is this the desired behavior for v3? Feels like this is a bug if there's no other way to get access to the request body in this scenario.
@bstoked @TMUNYU @DanielTongAwesome @MateRadz Can you confirm that you are all experiencing the same issue? The fact that the compatibility mode doesn't solve it for everyone might indicate a different problem. Please share a repro if possible.
I do not knot your internal schedule but for me it is a new issue as my function without any change in code worked for several days until the last ok at 25.08.2020, 13:15:05.009. The next call at 25.08.2020, 19:16:20.619 (UTC) was the first not working an it is like this till today. So for me it may have been related to your internal updates, if there where any. As mentioned when called directly from Test/Run on Azure Portal it works.
Found another work around for others. In my case I was using GET on the function. If you use POST instead the body will come in correctly. I am not using the FUNCTIONS_V2_COMPATIBILITY_MODE.
That's not true for me at least; the first time I tripped over this issue it was with a POST message
I stumbled on this while investigating why the request body received from a (deployed to azure) function app is empty. Contrary to the above, I don't see this behaviour running locally. Even with content-type set to application/json I can successfully pass along a non-empty body.
PS C:\Users\me\source\project> func -v 3.0.2931
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />
</ItemGroup>
</Project>
namespace my.namespace
{
public static class Notify
{
[FunctionName(nameof(Notify))]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "notify")] HttpRequest req,
[Queue("name", Connection = "connName")] IAsyncCollector<string> myDestinationQueue,
ILogger log)
{
using var r = new StreamReader(req.Body, Encoding.UTF8);
var bodyStr = await r.ReadToEndAsync();
await myDestinationQueue.AddAsync(bodyStr);
// do stuff...
return new OkObjectResult(1);
}
}
}
I do not knot your internal schedule but for me it is a new issue as my function without any change in code worked for several days until the last ok at 25.08.2020, 13:15:05.009. The next call at 25.08.2020, 19:16:20.619 (UTC) was the first not working an it is like this till today. So for me it may have been related to your internal updates, if there where any. As mentioned when called directly from Test/Run on Azure Portal it works.
The simplest workaround which worked for me was redeployment of function with MS provided example http trigger function. After that worked I copied my source to the function and after deploying again it started to work.
I tried to reproduce the issue with a new func
project however I couldn't
func --version
-> 3.0.2931
dotnet --version
-> 3.1.402
> func new ImageService --dotnet
> cd ImageService
> func init
(Add a HTTP Trigger)Swap code in the new HTTP Trigger class with this snippet
public static class CreatePDF
{
[FunctionName(nameof(CreatePDF))]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "createPDF")]
HttpRequestMessage req,
ILogger log)
{
var body = await req.Content.ReadAsStringAsync().ConfigureAwait(false);
log.LogInformation(body);
return new OkObjectResult(body);
}
}
public static class MergePDF
{
[FunctionName(nameof(MergePDF))]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "mergePDF")]
HttpRequest req,
ILogger log)
{
var reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true);
{
var body = await reader.ReadToEndAsync().ConfigureAwait(false);
log.LogInformation(body);
return new OkObjectResult(body);
}
}
}
@anthonychu The issue with @myarotskaya's git repo is the order of parameters
Once, the order of parameters is fixed, the request body comes through
I tried to reproduce the issue with a new
func
project however I couldn't
I can confirm this is now working for me with Microsoft.NET.Sdk.Functions 3.0.9, both in local emulator and in Azure itself, and with Get as well as Post.
Use Https instead of http with the default setup of an http trigger azure function , that worked for me
Ultimately i had to switch to POST and use in function Model Binding, and NOT rely on parsing the request body. It seems no matter how hard I try, the body is often empty when the azure function is 'waking up' (first hit on a cold function), but on subsequent hits it is valid and works.
FUNCTIONS_V2_COMPATIBILITY_MODE to true didn't do me any good.
This is my new start:
[FunctionName("GetComics")]
[FixedDelayRetry(5, "00:00:02")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)]
GetComicsRequest Request,
ILogger log
)
{
...
var Response = new ComicResponse()
{
Date = (Comics.Count > 0 ? Comics[0].Date : Request.Date != DateTimeHelper.ZERO_TIME ? Request.Date : DateTime.Now),
Comics = Comics
};
return new JsonResult(Response);
}
I have also been suffering with the issue of an empty body with a runtime v4 app based on C# .NET 6 LTS.
I have a working set of code that has run fine in production for years (earlier version of the runtime). After moving it to .NET 6 LTS and runtime v4, the following code at the start of the function definition was not returning the request body:
string sRequestBody = null;
if (oRequest.Body != null)
{
using (StreamReader oReader = new StreamReader(oRequest.Body))
{
sRequestBody = await oReader.ReadToEndAsync();
}
}
The function was originally declared as:
[FunctionName("TestPost")]
public static async Task<IActionResult> TestPost(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = TrainDataHttpRoutes.Test)]
ExecutionContext context, HttpRequest oRequest, ILogger oLog)
What fixed it was removing the ExecutionContext parameter:
[FunctionName("TestPost")]
public static async Task<IActionResult> TestPost(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = TrainDataHttpRoutes.Test)]
HttpRequest oRequest, ILogger oLog)
Just posting here in case helps others as this caused me a lot of frustration to figure out.
I have now suffered a recurrence of this issue. The above Azure Function has been running fine for the last 3 weeks has now suddenly stopped working with the issue again being an empty body. I've made no changes/done no deployments since 3 weeks ago. What was working yesterday has suddenly stopped working today with no change/intervention from me. The exact same test case (same request) that worked a week ago is not working today. This bug in Azure Functions is very frustrating.
Can anyone confirm if this has been resolved yet? On v4 and having the same issue.
Can anyone confirm if this has been resolved yet? On v4 and having the same issue.
I do not know your language, but in typescript this is working for me:
await request.json()
where request is HttpRequest class.
For others running into this issue, I found that switching to HttpRequestData
allowed me to access the request body without needing to change any other code.
Perhaps related to this note in the payload section documentation on .NET Isolated?
Type Description HttpRequest Use of this type requires that the app is configured with ASP.NET Core integration in .NET Isolated.
This gives you full access to the request object and overall HttpContext.HttpRequestData A projection of the request object.
Good day, I am getting an intermittent empty body from C# .NET 8 Http trigger Azure Function
I have also posted the issue on stackoverflow.
I am encountering an intermittent issue when calling a POST method hosted on Azure Functions using C# .NET 8 dotnet-isolated http trigger. The request body appears to be empty approximately 40% to 60% of the time without async and with async it is around 10%, and I am uncertain about the cause.
I have developed a basic function to serve as a mock API. Its sole purpose is to return an HTTP status code and a JSON object. In all cases, when I call the function, I receive a 200 response. However, in some cases, the response does not include a body.
Here is a code example with async:
[Function("TokenOk")]
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "TokenOk")] HttpRequest req)
{
_logger.LogInformation($"Executing TokenOk function.");
var json = new
{
AccessToken = "eyJhbGciOiJSUzI1....",
ExpiryInSeconds = 3600,
IssuedAtUTC = "2024-03-25T13:42:14.6599966Z"
};
// When I increase the delay to 100, to 1000, the empty body ratio gets less
await Task.Delay(10);
return new OkObjectResult(json);
}
Here is a code example without async:
[Function("TokenOk")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "TokenOk")] HttpRequest req)
{
_logger.LogInformation($"Executing TokenOk function.");
var json = new
{
AccessToken = "eyJhbGciOiJSUzI1....",
ExpiryInSeconds = 3600,
IssuedAtUTC = "2024-03-25T13:42:14.6599966Z"
};
return new OkObjectResult(json);
}
To investigate further, I have created a small console application to hit the endpoint multiple times and check for the presence of a response body:
Data in Response 710
Data in Response 711
Data in Response 712
Data in Response 713
Response 714 is empty
Data in Response 715
Response 716 is empty
Data in Response 717
Data in Response 718
Data in Response 719
Data in Response 720
Response 721 is empty
Response 722 is empty
Data in Response 723
Data in Response 724
Data in Response 725
Data in Response 726
Data in Response 727
Data in Response 728
Data in Response 729
Data in Response 730
Data in Response 731
Here is an example of the environment variables used in the Azure Function:
[
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "InstrumentationKey=...",
"slotSetting": false
},
{
"name": "AzureWebJobsStorage",
"value": "DefaultEndpointsProtocol=http..",
"slotSetting": false
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4",
"slotSetting": false
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet-isolated",
"slotSetting": false
},
{
"name": "WEBSITE_ENABLE_SYNC_UPDATE_SITE",
"value": "true",
"slotSetting": false
},
{
"name": "WEBSITE_RUN_FROM_PACKAGE",
"value": "1",
"slotSetting": false
},
{
"name": "WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED",
"value": "1",
"slotSetting": false
},
{
"name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
"value": "true",
"slotSetting": false
}
]
I tried switching IActionResult with HttpResponseData, but that didn't help. I attempted changing HttpResponseData to async. I even deleted the Azure Function and recreated it, but no luck. I also tried recreating the function locally and then deploying it. This issue only occurs once it's deployed to Azure; it works perfectly locally. I have let the console app that calls the post method run for 1000 times and I still get some with an empty body.
Thank you in advance.
HttpTrigger works incorrectly in the following conditions:
Microsoft.NET.Sdk.Functions
version3.0.2
request
variable is empty if request containsContent-Type: application/json
header (works ok with any otherContent-Type
values exceptapplication/json
). So in the example the empty response body will be returned which is unexpected.Investigative information
I've created the repository to demonstrate this issue. The source code of this repository is deployed to the Function App.
32894c31-74ac-4a98-8f94-fe6c76662d7d
Repro steps
POST https://netcore3httpbindingbug.azurewebsites.net/api/netcore3/qqq
request with some body andContent-Type: application/json
header.Expected behavior
Request's body is returned in the response.
Actual behavior
Request's body is not returned in the response.
Known workarounds
Do not send
Content-Type: application/json
header or send any other value in theContent-Type
header.Related information
The same code works correct in Azure Functions v2 on netcoreapp2.1 with
Microsoft.NET.Sdk.Functions
version1.0.29
and in ASP.NET Core 3.1 Web Application.There are two endpoints to check it (see the repository):
POST /netcore2/some-id
request with some body andContent-Type: application/json
headerPOST /aspnetcore3/some-id
request with some body andContent-Type: application/json
headerIn both cases the request body will be returned in the response (I didn't deploy it to any Function App but it's reproducible locally as well).