Create a function as follows on a default .net 8 isolated function app:
public class Function1
{
public Function1()
{
}
[Function("Function1")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
[FromQuery] bool includeSomething = false)
{
return new OkObjectResult($"Did you include something? {includeSomething}");
}
}
Run function app
Send get request to function endpoint: http://localhost:7107/api/Function1?includeSomething=False
Expected behavior
Expected response body: Did you include something? False
Actual behavior
Http Error - 500 Internal Server Error occurs
Function app console logs are as follows:
[2024-10-17T09:17:56.773Z] Function 'Function1', Invocation id '07a9025c-876f-4f43-a6a1-2421edad600c': An exception was thrown by the invocation.
[2024-10-17T09:17:56.775Z] Result: Function 'Function1', Invocation id '07a9025c-876f-4f43-a6a1-2421edad600c': An exception was thrown by the invocation.
Exception: Microsoft.Azure.Functions.Worker.FunctionInputConverterException: Error converting 1 input parameters for Function 'Function1': Cannot convert input parameter 'includeSomething' to type 'System.Boolean' from type 'System.String'. Error:System.Text.Json.JsonException: 'F' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
[2024-10-17T09:17:56.777Z] ---> System.Text.Json.JsonReaderException: 'F' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
[2024-10-17T09:17:56.780Z] at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
[2024-10-17T09:17:56.783Z] at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker)
[2024-10-17T09:17:56.784Z] at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first)
[2024-10-17T09:17:56.786Z] at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
[2024-10-17T09:17:56.799Z] at System.Text.Json.Utf8JsonReader.Read()
[2024-10-17T09:17:56.800Z] at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
[2024-10-17T09:17:56.802Z] --- End of inner exception stack trace ---
[2024-10-17T09:17:56.805Z] at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, JsonReaderException ex)
[2024-10-17T09:17:56.807Z] at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
[2024-10-17T09:17:56.813Z] at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.ContinueDeserialize(ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack)
[2024-10-17T09:17:56.817Z] at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsync(Stream utf8Json, CancellationToken cancellationToken)
[2024-10-17T09:17:56.820Z] at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken)
[2024-10-17T09:17:56.822Z] at Microsoft.Azure.Functions.Worker.Converters.JsonPocoConverter.GetConversionResultFromDeserialization(Byte[] bytes, Type type) in D:\a\_work\1\s\src\DotNetWorker.Core\Converters\JsonPocoConverter.cs:line 66
[2024-10-17T09:17:56.824Z] at Microsoft.Azure.Functions.Worker.Context.Features.DefaultFunctionInputBindingFeature.BindFunctionInputAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\Context\Features\DefaultFunctionInputBindingFeature.cs:line 97
[2024-10-17T09:17:56.828Z] at FromQueryTest.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\momsend\source\repos\FromQueryTest\FromQueryTest\obj\Debug\net8.0\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 31
[2024-10-17T09:17:56.831Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13
[2024-10-17T09:17:56.834Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /mnt/vss/_work/1/s/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 54
[2024-10-17T09:17:56.835Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 91
Stack: at Microsoft.Azure.Functions.Worker.Context.Features.DefaultFunctionInputBindingFeature.BindFunctionInputAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\Context\Features\DefaultFunctionInputBindingFeature.cs:line 97
[2024-10-17T09:17:56.837Z] at FromQueryTest.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\momsend\source\repos\FromQueryTest\FromQueryTest\obj\Debug\net8.0\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 31
[2024-10-17T09:17:56.840Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13
[2024-10-17T09:17:56.843Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /mnt/vss/_work/1/s/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 54
[2024-10-17T09:17:56.845Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 91.
[2024-10-17T09:17:56.862Z] Executed 'Functions.Function1' (Failed, Id=07a9025c-876f-4f43-a6a1-2421edad600c, Duration=217ms)
[2024-10-17T09:17:56.864Z] System.Private.CoreLib: Exception while executing function: Functions.Function1. System.Private.CoreLib: Result: Failure
Exception: Microsoft.Azure.Functions.Worker.FunctionInputConverterException: Error converting 1 input parameters for Function 'Function1': Cannot convert input parameter 'includeSomething' to type 'System.Boolean' from type 'System.String'. Error:System.Text.Json.JsonException: 'F' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
[2024-10-17T09:17:56.866Z] ---> System.Text.Json.JsonReaderException: 'F' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
[2024-10-17T09:17:56.868Z] at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
[2024-10-17T09:17:56.870Z] at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker)
[2024-10-17T09:17:56.873Z] at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first)
[2024-10-17T09:17:56.875Z] at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
[2024-10-17T09:17:56.877Z] at System.Text.Json.Utf8JsonReader.Read()
[2024-10-17T09:17:56.878Z] at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
[2024-10-17T09:17:56.880Z] --- End of inner exception stack trace ---
[2024-10-17T09:17:56.882Z] at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, JsonReaderException ex)
[2024-10-17T09:17:56.883Z] at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
[2024-10-17T09:17:56.886Z] at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.ContinueDeserialize(ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack)
[2024-10-17T09:17:56.889Z] at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsync(Stream utf8Json, CancellationToken cancellationToken)
[2024-10-17T09:17:56.890Z] at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken)
[2024-10-17T09:17:56.890Z] at Microsoft.Azure.Functions.Worker.Converters.JsonPocoConverter.GetConversionResultFromDeserialization(Byte[] bytes, Type type) in D:\a\_work\1\s\src\DotNetWorker.Core\Converters\JsonPocoConverter.cs:line 66
[2024-10-17T09:17:56.891Z] at Microsoft.Azure.Functions.Worker.Context.Features.DefaultFunctionInputBindingFeature.BindFunctionInputAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\Context\Features\DefaultFunctionInputBindingFeature.cs:line 97
[2024-10-17T09:17:56.892Z] at FromQueryTest.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\momsend\source\repos\FromQueryTest\FromQueryTest\obj\Debug\net8.0\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 31
[2024-10-17T09:17:56.893Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13
[2024-10-17T09:17:56.894Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /mnt/vss/_work/1/s/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 54
[2024-10-17T09:17:56.895Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 91
[2024-10-17T09:17:56.897Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88
Stack: at Microsoft.Azure.Functions.Worker.Context.Features.DefaultFunctionInputBindingFeature.BindFunctionInputAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\Context\Features\DefaultFunctionInputBindingFeature.cs:line 97
[2024-10-17T09:17:56.898Z] at FromQueryTest.DirectFunctionExecutor.ExecuteAsync(FunctionContext context) in C:\Users\momsend\source\repos\FromQueryTest\FromQueryTest\obj\Debug\net8.0\Microsoft.Azure.Functions.Worker.Sdk.Generators\Microsoft.Azure.Functions.Worker.Sdk.Generators.FunctionExecutorGenerator\GeneratedFunctionExecutor.g.cs:line 31
[2024-10-17T09:17:56.899Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 13
[2024-10-17T09:17:56.900Z] at Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.FunctionsHttpProxyingMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in /mnt/vss/_work/1/s/extensions/Worker.Extensions.Http.AspNetCore/src/FunctionsMiddleware/FunctionsHttpProxyingMiddleware.cs:line 54
[2024-10-17T09:17:56.901Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.InvokeFunctionAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 91
[2024-10-17T09:17:56.902Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request) in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 88.
Known workarounds
The obvious workaround is the use lowercase first letter true or false e.g.
http://localhost:7107/api/Function1?includeSomething=false
This will work.
To support pascal case we can use a string input parameter and parse it:
[Function("StringInputParam")]
public IActionResult StringInputParam([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
[FromQuery] string includeSomething)
{
bool convertedToBool = bool.Parse(includeSomething);
return new OkObjectResult($"Function2 Did you include something? {convertedToBool}");
}
Related information
The issue is the same whether you run the application locally or deployed in azure.
Can be replicated on a default .net isolated azure function app
Program.cs:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.Build();
host.Run();
Azure Logic Apps that use the Http Swagger action or the API Management action will automatically provide a "False" or "True" to query parameters coded as boolean, so I have to support both camel and pascal case when migrating to the isolated worker.
This is mostly just frustrating but there are simple ways to work around it.
It should also be noted that when I add services.AddMvc().AddNewtonsoftJson(); to the HostBuilder.ConfigureServices (in Program.cs) nothing changes. It still seems to use System.Text.Json
Repro steps
Create a function as follows on a default .net 8 isolated function app:
http://localhost:7107/api/Function1?includeSomething=False
Expected behavior
Expected response body:
Did you include something? False
Actual behavior
Http Error - 500 Internal Server Error occurs Function app console logs are as follows:
Known workarounds
The obvious workaround is the use lowercase first letter true or false e.g.
http://localhost:7107/api/Function1?includeSomething=false
This will work.To support pascal case we can use a string input parameter and parse it:
Related information
The issue is the same whether you run the application locally or deployed in azure.
Can be replicated on a default .net isolated azure function app
Program.cs:
host.json:
local.settings.json:
Azure Logic Apps that use the Http Swagger action or the API Management action will automatically provide a "False" or "True" to query parameters coded as boolean, so I have to support both camel and pascal case when migrating to the isolated worker.
This is mostly just frustrating but there are simple ways to work around it.