azure-functions-host: Using latest .NET Core 3.0 packages with Azure Functions v2 (like System.Text.Encodings.Web) causes "Method not found" issue due to assembly version mismatch

Is your question related to a specific version? If so, please specify:

Azure Functions v2

What language does your question apply to? (e.g. C#, JavaScript, Java, All)

C#

Question

From https://github.com/dotnet/corefx/issues/41534 (System.Text.Json: Method not found System.Text.Encodings.Web.TextEncoder.FindFirstCharacterToEncodeUtf8)

Works perfectly well in every project except Azure Functions (v2). Simply HTTP trigger an Azure Function and try and serialize (or deserialize) an object.

cc @electricessence, @fabiocav

Is there a workaround to this dependency version pinning issue?

This issue looks similar to https://github.com/Azure/azure-functions-host/issues/4906.

Here’s a repro with a similar error:

System.Private.CoreLib: Exception while executing function: Function1. TestDependency: Method not found: 'System.Text.Encodings.Web.JavaScriptEncoder System.Text.Encodings.Web.JavaScriptEncoder.get_UnsafeRelaxedJsonEscaping()'.
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <AzureFunctionsVersion>v2</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.29" />
    <PackageReference Include="System.Text.Json" Version="4.6.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>
public static class Function1
{
    [FunctionName("Function1")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        string name = req.Query["name"];

        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);

        var output = new MemoryStream();
        using (var writer = new Utf8JsonWriter(output, 
            new JsonWriterOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }))
        {
            writer.WriteString(Encoding.UTF8.GetBytes("name"), "Bob1");
            writer.Flush();
        }

        name = System.Text.Json.JsonSerializer.Serialize(Encoding.UTF8.GetString(output.ToArray()));

        return name != null
            ? (ActionResult)new OkObjectResult($"Hello, {name}")
            : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
    }
}
Http Functions:

        Function1: [GET,POST] http://localhost:7071/api/Function1

[10/7/2019 3:09:01 AM] Host lock lease acquired by instance ID '000000000000000000000000B068BFBB'.
[10/7/2019 3:09:07 AM] Executing HTTP request: {
[10/7/2019 3:09:07 AM]   "requestId": "a37a95c1-868d-484d-82d9-f9cc6e34ba3b",
[10/7/2019 3:09:07 AM]   "method": "GET",
[10/7/2019 3:09:07 AM]   "uri": "/api/Function1"
[10/7/2019 3:09:07 AM] }
[10/7/2019 3:09:07 AM] Executing 'Function1' (Reason='This function was programmatically called via the host APIs.', Id=c9432a44-ea43-4ad9-b45a-7b642c43f07c)
[10/7/2019 3:09:08 AM] Executed 'Function1' (Failed, Id=c9432a44-ea43-4ad9-b45a-7b642c43f07c)
[10/7/2019 3:09:08 AM] System.Private.CoreLib: Exception while executing function: Function1. TestDependency: Method not found: 'System.Text.Encodings.Web.JavaScriptEncoder System.Text.Encodings.Web.JavaScriptEncoder.get_UnsafeRelaxedJsonEscaping()'.
[10/7/2019 3:09:09 AM] Executed HTTP request: {
[10/7/2019 3:09:09 AM]   "requestId": "a37a95c1-868d-484d-82d9-f9cc6e34ba3b",
[10/7/2019 3:09:09 AM]   "method": "GET",
[10/7/2019 3:09:09 AM]   "uri": "/api/Function1",
[10/7/2019 3:09:09 AM]   "identities": [
[10/7/2019 3:09:09 AM]     {
[10/7/2019 3:09:09 AM]       "type": "WebJobsAuthLevel",
[10/7/2019 3:09:09 AM]       "level": "Admin"
[10/7/2019 3:09:09 AM]     }
[10/7/2019 3:09:09 AM]   ],
[10/7/2019 3:09:09 AM]   "status": 500,
[10/7/2019 3:09:09 AM]   "duration": 2444
[10/7/2019 3:09:09 AM] }

Looks like the .NET Core 2.2 dependencies are overriding the newer ones that the user code might bring in/rely on: https://github.com/Azure/azure-functions-host/blob/a63aeed826c4a1ee7c4e8c676bf7557c88a86ba1/src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj#L53-L66

For example: Microsoft.AspNetCore.App version 2.2.7 brings in the version 4.0.3.0 of the assembly where-as the version that S.T.Json depends on is 4.0.4.0 (this is the version that ships in-box with .NET Core 3.0 and is available as part of the latest 4.6.0 NuGet package).

The function output directory has the right dlls: image

However, Azure Functions is loading the older dll first (that comes built-in with the azure functions cli): image

image

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16 (2 by maintainers)

Most upvoted comments

I had this very same issue with my Blazor app. Changing the TargetFramework of my Blazor client app and shared library projects from netstandard2.1 to netstandard2.0 resolved the issue.

We’ll have a preview (with a supporting version of the CLI) available very soon. Please keep an eye on the announcement @espray linked above as we’ll update it once those bits become available.