Azure-functions-core-tools: JSON serialization differences locally and on Azure for Functions v3

Created on 30 Jan 2020  路  3Comments  路  Source: Azure/azure-functions-core-tools

That code when run locally (from VS, or VS Code using latest npm based func v3 core tools) behave differently from when deployed to Azure.

Run locally and you get: (the highlighted property names have not been mapped)

PS C:\> (Invoke-WebRequest -Uri http://localhost:7071/api/f1).Content
{"**identifier**":"a3c9ae75-52d7-40db-af92-58be363c61b5","**itemName**":"Item1","**description**":"This is the first item."}

Run in Azure and you get: (which is what I expect)

PS C:\> (Invoke-WebRequest -Uri https://askew.azurewebsites.net/api/f1).Content
{"id":"a3c9ae75-52d7-40db-af92-58be363c61b5","name":"Item1","desc":"This is the first item."}

Locally I tested with core tools version 3.0.2009, and dotnet version 3.1.101. I noticed that locally the runtime was still 3.0.12930. On Azure I deployed to West US, and the host runtime is already 3.0.13107. Not sure if this runtime difference is the cause.

Here's more information:
Function code:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace FunctionSerialisation
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "f1")] HttpRequest req, ILogger log)
        {
            var queryParams = req.GetQueryParameterDictionary();

            var model = new MyModel
            {
                Identifier = Guid.NewGuid().ToString(),
                ItemName = "Item1",
                Description = "This is the first item."
            };

            var ss = new JsonSerializerSettings
            {
                Formatting = Formatting.Indented
            };
            // This compiles but fails at runtime (locally and in Azure)
            //return Task.FromResult<IActionResult>(new JsonResult(model, ss));
            return Task.FromResult<IActionResult>(new JsonResult(model));
        }
    }
}

CSProj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.2.0" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="3.0.5" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.0.2" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Host.Storage" Version="3.0.14" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.2" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

Model class:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;

namespace FunctionSerialisation
{
    public class MyModel
    {
        [JsonProperty("id"), JsonPropertyName("id")]
        public string Identifier { get; set; }

        [JsonProperty("name"), JsonPropertyName("name")]
        public string ItemName { get; set; }

        [JsonProperty("desc"), JsonPropertyName("desc")]
        public string Description { get; set; }

    }
}

Most helpful comment

Hey @nzthiago - Sorry for the delay! I just checked locally with the following:

Azure Functions Core Tools (3.0.2245 Commit hash: 1d094e2f3ef79b9a478a1621ea7ec3f93ac1910d)
Function Runtime Version: 3.0.13139.0
dotnet version: 3.1.100

And got

PS C:\Users\mahoeger> (Invoke-WebRequest -Uri http://localhost:7071/api/f1).Content
{"id":"25a4aa6f-f22b-4cb4-aecc-19f3ae02b36b","name":"Item1","desc":"This is the first item."}

I ran it back with core tools 3.0.2009 and did see the incorrect response as well. Closing as resolved with latest!

All 3 comments

Assigning for validation. Need to test this against the latest version of Core Tools (matching the Azure Hosted version) and investigate impact.

Moving this to sprint 70 as the release is still in progress.

Hey @nzthiago - Sorry for the delay! I just checked locally with the following:

Azure Functions Core Tools (3.0.2245 Commit hash: 1d094e2f3ef79b9a478a1621ea7ec3f93ac1910d)
Function Runtime Version: 3.0.13139.0
dotnet version: 3.1.100

And got

PS C:\Users\mahoeger> (Invoke-WebRequest -Uri http://localhost:7071/api/f1).Content
{"id":"25a4aa6f-f22b-4cb4-aecc-19f3ae02b36b","name":"Item1","desc":"This is the first item."}

I ran it back with core tools 3.0.2009 and did see the incorrect response as well. Closing as resolved with latest!

Was this page helpful?
0 / 5 - 0 ratings