question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

CosmosDBAsyncCollector uses Newtonsoft instead of System.Text.Json (.NET Core 3.1 and Azure Function runtime version ~3)

See original GitHub issue

Adoption of System.Text.Json is encouraged for applications targeting .NET Core 3+. The CosmosDBAsyncCollector output binding uses Newtonsoft as its JSON Serializer.

For Azure Functions on runtime version ~3 targeting .NET Core 3.1 it would be preferred if all of the bindings directly supported System.Text.Json (preferably by default).

Repro steps

  1. Create an empty Cosmos DB database example-db collection example-collection.

  2. Create an Azure Function App project targeting runtime ~3 and .NET Core 3.1.

  3. Set example-db-connection-string in the local.settings.json.

  4. Target Azure Functions runtime ~3 and .NET Core 3.1, then add a FunctionExample.cs to your project with the following code:

  ...
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
  </PropertyGroup>
  ...
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace FunctionAppExample
{
    public class MyModel
    {
        [JsonPropertyName("id")]
        public string DocumentId { get; set; }
    }

    public static class FunctionExample
    {
        [FunctionName("FunctionExample")]
        public static async Task Run([TimerTrigger("0 */1 * * * *")] TimerInfo myTimer,
            [CosmosDB("example-db",
                "example-collection",
                ConnectionStringSetting = "example-db-connection-string")]
            IAsyncCollector<MyModel> output,
            ILogger log)
        {
            var thing = new MyModel
            {
                DocumentId = "abc"
            };

            await output.AddAsync(thing);
        }
    }
}
  1. Run the function host and allow FunctionExample to execute once.

  2. Inspect the document created by the function in example-collection .

Expected behavior

Document is serialized by System.Text.Json: image

Actual behavior

Document is serialized by Newtonsoft: image

Known workarounds

  • Use Newtonsoft on all models consumed in the bindings.
  • Explicitly perform the serialization outside of the bindings.

Related information

Relevant code:

Possibly other Azure Function bindings and triggers follow the same pattern (not investigated).

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:5
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
ealsurcommented, Dec 13, 2021

V3 SDK uses Newtonsoft.Json as default serialization engine, so it’s the same behavior for the 4.0.0-preview package. But you can plug in/replace with any serializer you want. We don’t have official docs yet but you can leverage the new serialization factory. In your Startup.cs file:

[assembly: FunctionsStartup(typeof(FunctionApp1.Startup))]
namespace FunctionApp1
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<ICosmosDBSerializerFactory, MyCosmosDBSerializerFactory>();
        }
    }

    public class MyCosmosDBSerializerFactory : ICosmosDBSerializerFactory
    {
        public CosmosSerializer CreateSerializer()
        {
            var options = new JsonSerializerOptions();

            return new CosmosSystemTextJsonSerializer(options);
        }
    }
}

You can have any custom implementation of CosmosSerializer, for example, one for System.Text.Json: https://github.com/Azure/azure-cosmos-dotnet-v3/tree/master/Microsoft.Azure.Cosmos.Samples/Usage/SystemTextJson

0reactions
bmwaechtercommented, Dec 10, 2021

@ealsur I noticed this PR #717 that seems to upgrade to the V3 SDK, should be expect that if we are using the preview nuget package for the cosmos extension? I tried it recently and it didn’t seem to respect system.text.json annotation, which I assume means we are still using Newtonsoft under the hood.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Migrate from Newtonsoft.Json to System.Text.Json - .NET
Json namespace provides functionality for serializing to and deserializing from JavaScript Object Notation (JSON). The System.Text.Json library ...
Read more >
Azure Functions runtime versions overview
Azure Functions supports multiple versions of the runtime. Learn the differences between them and how to choose the one that's right for ...
Read more >
Should you use Newtonsoft.Json or System.Text. ...
I prefer System.text.json, but need newtonsoft for azure cosmos db and for openApi generation with azure functions.
Read more >
Is it any way we can use the latest json.net library to an ...
I have an Azure Function under .net core 3.1. In that function I have installed the latest Newtonsoft.Json .net library (currently version 13.0....
Read more >
System.Text.Json.JsonPropertyName not working for ...
This article explains how to fix an annoying issue with Microsoft's SDK for CosmosDb v3 – it comes with a Newtonsoft.Json dependency, that...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found