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

.NET 9 Blazor WebAssembly: Rendering exception due to recursive type definition #109931

Open
1 task done
zyreon-sg opened this issue Nov 14, 2024 · 11 comments
Open
1 task done
Assignees
Labels
arch-wasm WebAssembly architecture area-Codegen-Interpreter-mono os-browser Browser variant of arch-wasm
Milestone

Comments

@zyreon-sg
Copy link

zyreon-sg commented Nov 14, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Upgrading my .NET 8 Blazor WebAssembly application to .NET 9 lead to frontend rendering issues. In my specific case, I'm using a type derived from Ardalis.SmartEnum to display certain information. The SmartEnum class by Ardalis uses a recursive type where it references the derived class itself as a type parameter.

The result of this behavior is a completely defective rendering of the respective page. The console states the following error:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Could not resolve field token 0x04000001, due to: Could not set up parent class, due to: Recursive type definition detected Ardalis.SmartEnum.SmartEnum`1 assembly:Ardalis.SmartEnum.dll type:SmartEnum`1 member:(null) assembly:Demo.dll type:TestEnum member:(null)
System.BadImageFormatException: Could not resolve field token 0x04000001, due to: Could not set up parent class, due to: Recursive type definition detected Ardalis.SmartEnum.SmartEnum`1 assembly:Ardalis.SmartEnum.dll type:SmartEnum`1 member:(null) assembly:Demo.dll type:TestEnum member:(null)
File name: 'Demo'
   at Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__7_0(RenderTreeBuilder builder)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)

Expected Behavior

Rendering of the page succeeds as with .NET 8.

Steps To Reproduce

  1. Create a Blazor WebAssembly Standalone App (using .NET 9 PWA with example pages)
  2. Include a reference to Ardalis.SmartEnum via NuGet
<PackageReference Include="Ardalis.SmartEnum" Version="8.1.0" />
  1. Create a new class derived from SmartEnum
using Ardalis.SmartEnum;

public class TestEnum(string name, int value) : SmartEnum<TestEnum>(name, value)
{
    public static readonly TestEnum Default = new(nameof(Default), 0);
}
  1. Append the following code to the Home.razor example page
@if (Test == TestEnum.Default)
{
    <p>Value of test enum is default</p>
}

@code {
    public TestEnum Test => TestEnum.Default;
}
  1. Build and start the application, which will result in a rending exception on load

Exceptions (if any)

System.BadImageFormatException

.NET Version

9.0

Anything else?

Issue at Ardalis.SmartEnum: ardalis/SmartEnum#556

@soenneker
Copy link

This problem has stopped our .NET 8 -> 9 migration.

@soenneker
Copy link

soenneker commented Nov 15, 2024

@javiercn Could you or your team please take a look at this? This is blocking a large migration effort we have in progress. Thanks.

Or even some sort of workaround would be good...

@DataByte-James
Copy link

I have posted a temporary fix in the smartenum repository. The issue is the declaration of the array

static readonly Lazy<TEnum[]> _enumOptions = new Lazy<TEnum[]>(GetAllOptions, LazyThreadSafetyMode.ExecutionAndPublication);

I changed it to the below and it now works. Something odd there.

static readonly Lazy<List<TEnum>> _enumOptions = new Lazy<List<TEnum>>(GetAllOptions, LazyThreadSafetyMode.ExecutionAndPublication);

@javiercn
Copy link
Member

javiercn commented Nov 18, 2024

@soenneker thanks for contacting us.

Does this happen during development or does it happen after you publish?

@soenneker
Copy link

@javiercn thanks for getting back. This happens during development (debug etc), and not only when published.

@zyreon-sg
Copy link
Author

@javiercn Same for me. I can confirm that this issue exists with both local debugging and published applications (as tested with a solution being published to a Docker image using mcr.microsoft.com/dotnet/aspnet:9.0 as base).

@javiercn javiercn transferred this issue from dotnet/aspnetcore Nov 18, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Nov 18, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Nov 18, 2024
@javiercn
Copy link
Member

javiercn commented Nov 18, 2024

@slowfight @soenneker thanks for the additional details.

This seems like a runtime issue, as this worked in 8.0. I can't think of a reason why we would be able to cause a BadImage exception.

@javiercn javiercn added arch-wasm WebAssembly architecture and removed untriaged New issue has not been triaged by the area owner labels Nov 18, 2024
Copy link
Contributor

Tagging subscribers to 'arch-wasm': @lewing
See info in area-owners.md if you want to be subscribed.

@pavelsavara
Copy link
Member

Probably related to mono/mono#15760

cc @BrzVlad

@BrzVlad
Copy link
Member

BrzVlad commented Nov 25, 2024

Not convinced they are related. This reproduces on desktop and I confirm it is a runtime regression from net8.

@BrzVlad
Copy link
Member

BrzVlad commented Nov 25, 2024

Regression caused by e5f0c36

@vcsjones vcsjones removed the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-wasm WebAssembly architecture area-Codegen-Interpreter-mono os-browser Browser variant of arch-wasm
Projects
None yet
Development

No branches or pull requests

7 participants