-
Notifications
You must be signed in to change notification settings - Fork 191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WriteAsJsonAsync throws exception when using NewtonsoftJson serializer #2735
Comments
I'm having thesame exception when using: public async Task<HttpResponseData> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
HttpRequestData reqData,
[DurableClient] DurableTaskClient client)
{
var request = await reqData.ReadFromJsonAsync<MyModel>(); A bug for sure. |
Hi, I wasn't able to repro the issue you reported. Could you try again with all the latest packages? Here is what I tried which ended up working without issues (v1 of the worker): csproj (functions version v4 | .net8) <ItemGroup>
<PackageReference Include="Microsoft.Azure.Core.NewtonsoftJson" Version="2.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.23.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.18.1" />
</ItemGroup> Program.cs public static void Main(string[] args)
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults((IFunctionsWorkerApplicationBuilder builder) =>
{
builder.Services.Configure<WorkerOptions>(workerOptions =>
{
var settings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.NullValueHandling = NullValueHandling.Ignore;
workerOptions.Serializer = new NewtonsoftJsonObjectSerializer(settings);
});
})
.Build();
host.Run();
} MyHttpFunction.cs [Function("MyIsolatedFunction")]
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestData request)
{
var response = request.CreateResponse(HttpStatusCode.OK);
await response.WriteAsJsonAsync(new { Name="Error"});
return response;
} Core Tools
New ModelIt's also worth noting we have a new model we suggest folks update to: csproj (functions version v4 | .net8)
Program.cs
MyHttpFunction.cs [Function("MyHttpFunction")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult(new { Name="Error"});
} |
@liliankasem thank you for the response, unfortunately it doesn't work for me. If I use the packages from the The New Model version doesn't use the Newtonsoft.Json serializer.
What should I change? |
Can you compare your project with this sample and see what is different? https://github.com/liliankasem/dni-function-newtonsoft-sample/tree/main |
@liliankasem your sample project proves that my previous statement was right. I've made a few changes to your project: https://github.com/CSharpBender/dni-function-newtonsoft-sample
|
When using AspNetCore integration, the default is to disallow synchronous IO. This default comes from AspNetCore, not functions. It also so happens the NewtonsoftJsonObjectSerializer is completely synchronous, meaning these are not compatible by default. To enable synchronous IO, please add the following to your startup. This will enable Newtonsoft.Json usage: services.Configure<KestrelServerOptions>(options => options.AllowSynchronousIO = true); |
@jviau I'm not satisfied with your response because this is not mentioned in the Microsoft Guide |
@CSharpBender thank you pointing out the gap in the docs, we will add this information soon. |
Wait, how is this considered closed? the method is literally called WriteAsJsonAsync, and is essentially exactly what the error message is saying to do to resolve itself, but the solution to making WriteAsJsonAsync work without errors is to AllowSynchronousIO? That may be considered a workaround, but is certainly not a resolution. |
@ewillman we do not own the But the reasoning is also simple: Newtonsoft.Json does not support asynchronous serialization/deserialization, so the implementation falls back to synchronous. |
The synchronous issue also only applies to // need <PackageReference Include="Microsoft.Azure.Core.NewtonsoftJson" Version="2.0.0" /> for this
services.AddMvc().AddNewtonsoftJson(); |
Description
In Azure Functions isolated model an exception is thrown when overriding the serializer from ConfigureFunctionsWebApplication() and
response.WriteAsJsonAsync()
is used:System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
I followed the Microsoft guide for migrating an in-process Azure function to the isolated model which clearly states that I need to override the Json serializer in ConfigureFunctionsWebApplication and use
services.AddMvc().AddNewtonsoftJson().
While searching for a fix to my issue I found issue1 and issue2
Steps to reproduce
Exception is thrown:
System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
If I remove this line the exception disappears but the serialization is wrong because I'm using NewtonsoftJson attributes.
workerOptions.Serializer = new NewtonsoftJsonObjectSerializer(settings);
also this breaks the swagger definition.Another workaround is to serialize the object myself and use the
WriteAsync
method instead ofWriteAsJsonAsync
The text was updated successfully, but these errors were encountered: