Azure / azure-functions-signalrservice-extension

Azure Functions bindings for SignalR Service. Project moved to https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/signalr/Microsoft.Azure.WebJobs.Extensions.SignalRService .
MIT License
97 stars 46 forks source link

AddNewtonsoftJson causes Azure App Service to partially break #261

Closed rockgecko-development closed 1 year ago

rockgecko-development commented 2 years ago

Adding SignalR to a Azure Functions project that is using builder.Services.AddControllers().AddNewtonsoftJson to customise the project's json serialization, causes the project to partially break in Azure. Http API endpoints still work, but Portal will report errors like Azure Functions runtime is unreachable when trying to view the list of Functions, or

Unable to fetch the host status of your function app. To use log streaming, please make sure your function host is running.

When trying to view the Log Stream.

SignalRTrigger methods return errors like {"type":3,"invocationId":"0","error":"Invocation failed, status code 500"} when invoked from the client.

The specific code that causes the issue is:

public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
          builder.Services.AddControllers().AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                options.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
                options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;

            });
}
}

The extension is from package Microsoft.AspNetCore.Mvc.NewtonsoftJson.

Here's a minimum reproduceable example: https://github.com/rockgecko-development/AzureSignalR-samples/commit/ac9c07b1ca6749f3f338ef00b1837b2d16907215

Deploy this slightly modified BidirectionChat to a Azure Function App, and go to the Functions blade (that lists all the functions in the app). You should get a yellow banner Azure Functions runtime is unreachable or similar. The SendToGroup / Broadcast methods will return Invocation failed, status code 500. Then, delete these lines: https://github.com/rockgecko-development/AzureSignalR-samples/commit/ac9c07b1ca6749f3f338ef00b1837b2d16907215#diff-3a405bf02d5f438e152ff87e5c0a8175b3721e82afe2eaf1ca344833ad5cbf07R36-R42 Lines 36-42

and redeploy.

This issue took several days to track down, because there were no relevant error messages anywhere that indicated the problem.

My unanswered questions are:

  1. Why does AddNewtonsoftJson break it?
  2. What is the right way to set the default UTC date time handling and camel casing serialization for all of my own HttpTrigger functions?
  3. What is the right way to set the default date time handling and camel casing serialization for my SignalR requests and responses?
  4. Could there be better error logging for Azure Function Apps that partially fail to initialise, or did I miss somewhere? Part of the problem was the issue prevented me from even viewing Log Streaming
Y-Sindo commented 2 years ago

I have reproduced your problem and got some preliminary conclusions. First of all, the problem caused by AddNewtonsoftJson is not particular to SignalR trigger. I have used a HTTP trigger locally without SignalR and encountered the same result. I suspect AddNewtonsoftJson overwrites some function-specified dependencies. For the root cause, we will try to ask help from Azure Function team. For your other questions, we need further exploration. Will come back to you soon.

rockgecko-development commented 2 years ago

Thanks for taking a look so soon.

I have used a HTTP trigger locally without SignalR and encountered the same result

I'm not sure what you mean here, all of my issues occur in Portal and the deployed app, not locally.

It is certainly related to adding SignalR - my Function App was working before I added SignalR the first time, and I still have several other Function Apps configured with AddNewtonsoftJson, and no SignalR triggers, working fine (and with Log Streaming and Functions blades working correctly in Portal).

Y-Sindo commented 2 years ago

I just also reproduced the problem online with an HttpTrigger and AddNewtonsoftJson. Do your other Functions Apps have any kind of triggers such as http trigger?

Y-Sindo commented 2 years ago
  1. What is the right way to set the default date time handling and camel casing serialization for my SignalR requests and responses?

It is OK to use JsonConvert.DefaultSettings to customize SignalR messages sent and received in SignalR function extension in transient mode( the default transport mode). We will collect and sort out the problems about customizing json serialization and write a doc.

Why does AddNewtonsoftJson break it?

What is the right way to set the default UTC date time handling and camel casing serialization for all of my own HttpTrigger functions?

Could there be better error logging for Azure Function Apps that partially fail to initialise, or did I miss somewhere? Part of the problem was the issue prevented me from even viewing Log Streaming

For your other questions, we will work together with Azure functions team to provide you answers.

rockgecko-development commented 1 year ago

You were right, this issue was not specific to SignalR. Adding builder.Services.AddControllers() is enough to break a lot of Azure function apps' function bindings, in this case the SignalRTrigger bindings. Switching to JsonConvert.DefaultSettings worked, and I have now upgraded to the new method to explicitly set the JSON serialization settings