Skip to content
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

System.Text.Json SourceGenerator results in a compile error with a List<> of enums with a JsonConverter #61860

Closed
AshleighAdams opened this issue Nov 20, 2021 · 2 comments · Fixed by #62595
Assignees
Milestone

Comments

@AshleighAdams
Copy link

AshleighAdams commented Nov 20, 2021

Description

Attempting to define a JsonSerializerContext against a type that has a List<T> where T ultimately contains an enum with JsonConverter defined results in the following compile error:

TestSerializationContext.TestEnum.g.cs(19,90,19,113): error CS0103: The name 'GetConverterFromFactory' does not exist in the current context

Reproduction Steps

Test.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

Program.cs:

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

return;

[JsonSourceGenerationOptions(
	PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
	GenerationMode = JsonSourceGenerationMode.Serialization | JsonSourceGenerationMode.Metadata,
	WriteIndented = false)]
[JsonSerializable(typeof(TestStruct))]
internal partial class TestSerializationContext : JsonSerializerContext
{
}

internal struct TestStruct
{
	public List<TestEnum> Children { get; set; }
}

[JsonConverter(typeof(JsonStringEnumConverter))]
internal enum TestEnum
{
	Aye, Bee, Cee
}

Then dotnet build or build within Visual Studio (2022).

Expected behavior

Expected the build to succeed.

Actual behavior

Build fails with:

Build started...
1>------ Build started: Project: Test, Configuration: Debug Any CPU ------
1>C:\Git\Test\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\TestSerializationContext.TestEnum.g.cs(19,90,19,113): error CS0103: The name 'GetConverterFromFactory' does not exist in the current context
1>Done building project "Test.csproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Regression?

I don't think this is applicable, however, converting the test sample to .NET 5 in the repro steps results in the same error (after adding a reference to System.Text.Json 6.0.0.0).

Known Workarounds

Removing the JsonConverter attribute, however it results in different json output, using integers instead of strings, which is okay for my case as I control both producing and consuming, I did not search for other workarounds beyond this.

Configuration

$ dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.100
 Commit:    9e8b04bbff

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.100\

Host (useful for support):
  Version: 6.0.0
  Commit:  4822e3c3aa

.NET SDKs installed:
  6.0.100 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other information

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Nov 20, 2021
@ghost
Copy link

ghost commented Nov 20, 2021

Tagging subscribers to this area: @dotnet/area-system-text-json
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Attempting to define a serialization context against a type that has a List<T> where T ultimately contains an enum with JsonConverter defined results in the following compile error:

TestSerializationContext.TestEnum.g.cs(19,90,19,113): error CS0103: The name 'GetConverterFromFactory' does not exist in the current context

Reproduction Steps

Test.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

Program.cs:

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

return;

[JsonSourceGenerationOptions(
	PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
	GenerationMode = JsonSourceGenerationMode.Serialization | JsonSourceGenerationMode.Metadata,
	WriteIndented = false)]
[JsonSerializable(typeof(TestStruct))]
internal partial class TestSerializationContext : JsonSerializerContext
{
}

internal struct TestStruct
{
	public List<TestEnum> Children { get; set; }
}

[JsonConverter(typeof(JsonStringEnumConverter))]
internal enum TestEnum
{
	Aye, Bee, Cee
}

Then dotnet build or build within Visual Studio (2022).

Expected behavior

Expected the build to succeed.

Actual behavior

Build fails with:

Build started...
1>------ Build started: Project: Test, Configuration: Debug Any CPU ------
1>C:\Git\Test\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\TestSerializationContext.TestEnum.g.cs(19,90,19,113): error CS0103: The name 'GetConverterFromFactory' does not exist in the current context
1>Done building project "Test.csproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Regression?

I don't think this is applicable, however, converting the test sample to .NET 5 in the repro steps results in the same error (after adding a reference to System.Text.Json 6.0.0.0).

Known Workarounds

Removing the JsonConverter attribute, however it results in different json output, using integers instead of strings, which is okay for my case as I control both producing and consuming, I did not search for other workarounds beyond this.

Configuration

$ dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.100
 Commit:    9e8b04bbff

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.100\

Host (useful for support):
  Version: 6.0.0
  Commit:  4822e3c3aa

.NET SDKs installed:
  6.0.100 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other information

No response

Author: AshleighAdams
Assignees: -
Labels:

area-System.Text.Json, untriaged

Milestone: -

@jeffhandley jeffhandley added this to the 7.0.0 milestone Nov 20, 2021
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Nov 20, 2021
@jeffhandley jeffhandley removed this from the 7.0.0 milestone Nov 20, 2021
@eiriktsarpalis eiriktsarpalis added the untriaged New issue has not been triaged by the area owner label Nov 22, 2021
@eiriktsarpalis
Copy link
Member

Minimal reproduction:

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

System.Console.WriteLine();

[JsonSerializable(typeof(TestEnum))] // comment out to induce error
[JsonSerializable(typeof(List<TestEnum>))]
internal partial class TestSerializationContext : JsonSerializerContext
{
}

[JsonConverter(typeof(JsonStringEnumConverter))]
public enum TestEnum
{
	Aye, Bee, Cee
}

Generated code for types using converter factories depend on a GetConverterFromFactory helper method being generated in the context. However, the fact that TestEnum is only introduced as generic parameter in the JsonSerializable declarations appears to fool the generator into believing that such a helper is not needed.

As a temporary workaround you could try declaring the enum type itself as JsonSerializable and everything should work as expected.

Related to #62079 and #58267. We should fix this in conjunction with #62079.

@eiriktsarpalis eiriktsarpalis removed the untriaged New issue has not been triaged by the area owner label Dec 2, 2021
@eiriktsarpalis eiriktsarpalis added this to the 6.0.x milestone Dec 2, 2021
@eiriktsarpalis eiriktsarpalis self-assigned this Dec 2, 2021
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Dec 9, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Dec 10, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jan 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
3 participants