Skip to content

[Microsoft.XmlSerializer.Generator] Throws on internal types even when generated assembly is in the same scope #125968

@Vwwork

Description

@Vwwork

Description

The generator does not generate serializers for internal types, even though the generated XmlSerializers code runs in the same assembly and can access them.

Reproduction Steps

  1. Create a new console project:
dotnet new console -o MyApp
  1. Add the NuGet package and CLI tool reference:
dotnet add package Microsoft.XmlSerializer.Generator

Then add to MyApp.csproj:

<PropertyGroup>
  <SGenVerbose>true</SGenVerbose>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.XmlSerializer.Generator" Version="10.0.5" />
  <DotNetCliToolReference Include="Microsoft.XmlSerializer.Generator" Version="10.0.5" />
</ItemGroup>
  1. Replace Program.cs with:
using System.Reflection;

public static class Program
{
    public static void Main()
    {
        var instance = new MyInternalClass
        {
            Value = "Hello, World!"
        };

        var serializer = Assembly
            .LoadFrom(Path.Combine(AppContext.BaseDirectory, "MyApp.XmlSerializers.dll"))
            .CreateInstance("Microsoft.Xml.Serialization.GeneratedAssembly.MyInternalClassSerializer");

        Console.WriteLine(instance.Value);
        Console.WriteLine(serializer);
    }
}

internal class MyInternalClass
{
    public required string Value;
}
  1. Run with internal - observe the warning and that serializer is null:
dotnet run -v detailed

Expected behavior

The generator creates XmlSerializers correctly, since the generated code is compiled within the same assembly scope and can process internal types.

Actual behavior

Build log shows generator ignoring MyInternalClass:

Importing MyInternalClass (3/3)
Ignoring 'MyInternalClass'.
MyInternalClass is inaccessible due to its protection level. Only public types can be processed.

Regression?

No response

Known Workarounds

It is possible to temporarily change internal to public and run generation:

dotnet run

Then switch back to internal and run without rebuilding:

dotnet run --no-build

However, this only works until the next build, after which the issue reappears. This proves that the generated serializer has no runtime issues with internal types.

Configuration

  • .NET 10
  • Windows 10.0.26200
  • x64

Other information

In System.Private.Xml internal types are rejected too early, even when they are actually visible from the generated code context. The issue is caused by this check in Types.cs, which blindly rejects the internal type based on accessibility, without accounting for cases where the type is still visible/usable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions