microsoft / fluentui-blazor

Microsoft Fluent UI Blazor components library. For use with ASP.NET Core Blazor applications
https://www.fluentui-blazor.net
MIT License
3.3k stars 305 forks source link

fix: FluentMenu broken in published release build #280

Closed juho-hanhimaki closed 1 year ago

juho-hanhimaki commented 1 year ago

🐛 Bug Report

I have a basic FluentMenu.

image

On local development build everything works great. On a published release build clicking the FluentMenuItem causes an exception. There are no other warnings or exceptions visible in dev tools.

blazor.webassembly.js:1 

       Uncaught (in promise) Error: System.InvalidOperationException: There was an error parsing the event arguments. EventId: '8'.
 ---> System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, Microsoft.Fast.Components.FluentUI.MenuChangeEventArgs Path: $ | LineNumber: 0 | BytePositionInLine: 1.
 ---> System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, Microsoft.Fast.Components.FluentUI.MenuChangeEventArgs
   Exception_EndOfInnerExceptionStack
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& , Utf8JsonReader& , NotSupportedException )
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(Type , Utf8JsonReader& , ReadStack& )
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1[[Microsoft.Fast.Components.FluentUI.MenuChangeEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].OnTryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , MenuChangeEventArgs& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.Fast.Components.FluentUI.MenuChangeEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].TryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , MenuChangeEventArgs& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.Fast.Components.FluentUI.MenuChangeEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].ReadCore(Utf8JsonReader& , JsonSerializerOptions , ReadStack& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.Fast.Components.FluentUI.MenuChangeEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].ReadCoreAsObject(Utf8JsonReader& , JsonSerializerOptions , ReadStack& )
   at System.Text.Json.JsonSerializer.ReadFromSpan[Object](ReadOnlySpan`1 , JsonTypeInfo , Nullable`1 )
   at System.Text.Json.JsonSerializer.ReadFromSpan[Object](ReadOnlySpan`1 , JsonTypeInfo )
   at System.Text.Json.JsonSerializer.Deserialize(String , Type , JsonSerializerOptions )
   at Microsoft.AspNetCore.Components.Web.WebEventData.ParseEventArgsJson(Renderer , JsonSerializerOptions , UInt64 , String , JsonElement )
   Exception_EndOfInnerExceptionStack
   at Microsoft.AspNetCore.Components.Web.WebEventData.ParseEventArgsJson(Renderer , JsonSerializerOptions , UInt64 , String , JsonElement )
   at Microsoft.AspNetCore.Components.Web.WebEventData.Parse(Renderer , JsonSerializerOptions , WebEventDescriptor , JsonElement )
   at Microsoft.AspNetCore.Components.Web.WebEventData.Parse(Renderer , JsonSerializerOptions , JsonElement , JsonElement )
   at Microsoft.AspNetCore.Components.RenderTree.WebRenderer.WebRendererInteropMethods.DispatchEventAsync(JsonElement eventDescriptor, JsonElement eventArgs)
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.InvokeSynchronously(JSRuntime , DotNetInvocationInfo& , IDotNetObjectReference , String )
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(JSRuntime , DotNetInvocationInfo , String )
    at Object.endInvokeDotNetFromJS (**************/_framework/blazor.webassembly.js:1:3549)
    at Object.Xt [as endInvokeDotNetFromJS] (**************/_framework/blazor.webassembly.js:1:63231)
    at Object.Gt [as invokeJSFromDotNet] (**************/_framework/blazor.webassembly.js:1:62728)
    at Object.Ii (**************/_framework/dotnet.7.0.1.16jbry1adl.js:5:71465)
    at _mono_wasm_invoke_js_blazor (**************/_framework/dotnet.7.0.1.16jbry1adl.js:14:103886)
    at wasm://wasm/00992aee:wasm-function[313]:0x1d4d6
    at wasm://wasm/00992aee:wasm-function[283]:0x1c904
    at wasm://wasm/00992aee:wasm-function[221]:0xdff4
    at wasm://wasm/00992aee:wasm-function[220]:0xce93
    at wasm://wasm/00992aee:wasm-function[8113]:0x1a215b

endInvokeDotNetFromJS   @   blazor.webassembly.js:1
Xt  @   blazor.webassembly.js:1
Gt  @   blazor.webassembly.js:1
Ii  @   dotnet.7.0.1.16jbry1adl.js:5
_mono_wasm_invoke_js_blazor @   dotnet.7.0.1.16jbry1adl.js:14
$func313    @   00992aee:0x1d4d6
$func283    @   00992aee:0x1c904
$func221    @   00992aee:0xdff4
$func220    @   00992aee:0xce93
$func8113   @   00992aee:0x1a215b
$func2054   @   00992aee:0x85bb8
$func2059   @   00992aee:0x86220
$func2086   @   00992aee:0x882df
$mono_wasm_invoke_method_ref    @   00992aee:0x9bcf
Module._mono_wasm_invoke_method_ref @   dotnet.7.0.1.16jbry1adl.js:14
_Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_BeginInvokeDotNet    @   _Microsoft_AspNetCor…eginInvokeDotNet:29
beginInvokeDotNetFromJS @   blazor.webassembly.js:1
b   @   blazor.webassembly.js:1
invokeMethodAsync   @   blazor.webassembly.js:1
(anonymous) @   blazor.webassembly.js:1
invokeWhenHeapUnlocked  @   blazor.webassembly.js:1
S   @   blazor.webassembly.js:1
A   @   blazor.webassembly.js:1
dispatchGlobalEventToAllElements    @   blazor.webassembly.js:1
(anonymous) @   blazor.webassembly.js:1
onGlobalEvent   @   blazor.webassembly.js:1
emit    @   web-components.min.js:1
$emit   @   web-components.min.js:1
invoke  @   web-components.min.js:21
handleMenuItemClick @   web-components.min.js:21
(anonymous) @   web-components.min.js:183
handleEvent

That's all the info I have at this point. I can try to come up with minimal repro in few days.

💻 Repro or Code Sample

🤔 Expected Behavior

😯 Current Behavior

💁 Possible Solution

🔦 Context

🌍 Your Environment

<PackageReference Include="Microsoft.Fast.Components.FluentUI" Version="2.0.0-rc-2" />
juho-hanhimaki commented 1 year ago

Similar issue trying to dismiss FluentDialog by clicking outside the dialog.

Uncaught (in promise) Error: System.InvalidOperationException: There was an error parsing the event arguments. EventId: '5'.
 ---> System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, Microsoft.Fast.Components.FluentUI.DialogEventArgs Path: $ | LineNumber: 0 | BytePositionInLine: 1.
 ---> System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, Microsoft.Fast.Components.FluentUI.DialogEventArgs
   Exception_EndOfInnerExceptionStack
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& , Utf8JsonReader& , NotSupportedException )
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(Type , Utf8JsonReader& , ReadStack& )
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1[[Microsoft.Fast.Components.FluentUI.DialogEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].OnTryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , DialogEventArgs& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.Fast.Components.FluentUI.DialogEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].TryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , DialogEventArgs& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.Fast.Components.FluentUI.DialogEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].ReadCore(Utf8JsonReader& , JsonSerializerOptions , ReadStack& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.Fast.Components.FluentUI.DialogEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].ReadCoreAsObject(Utf8JsonReader& , JsonSerializerOptions , ReadStack& )
   at System.Text.Json.JsonSerializer.ReadFromSpan[Object](ReadOnlySpan`1 , JsonTypeInfo , Nullable`1 )
   at System.Text.Json.JsonSerializer.ReadFromSpan[Object](ReadOnlySpan`1 , JsonTypeInfo )
   at System.Text.Json.JsonSerializer.Deserialize(String , Type , JsonSerializerOptions )
   at Microsoft.AspNetCore.Components.Web.WebEventData.ParseEventArgsJson(Renderer , JsonSerializerOptions , UInt64 , String , JsonElement )
   Exception_EndOfInnerExceptionStack
   at Microsoft.AspNetCore.Components.Web.WebEventData.ParseEventArgsJson(Renderer , JsonSerializerOptions , UInt64 , String , JsonElement )
   at Microsoft.AspNetCore.Components.Web.WebEventData.Parse(Renderer , JsonSerializerOptions , WebEventDescriptor , JsonElement )
   at Microsoft.AspNetCore.Components.Web.WebEventData.Parse(Renderer , JsonSerializerOptions , JsonElement , JsonElement )
   at Microsoft.AspNetCore.Components.RenderTree.WebRenderer.WebRendererInteropMethods.DispatchEventAsync(JsonElement eventDescriptor, JsonElement eventArgs)
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.InvokeSynchronously(JSRuntime , DotNetInvocationInfo& , IDotNetObjectReference , String )
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(JSRuntime , DotNetInvocationInfo , String )
    at Object.endInvokeDotNetFromJS (***********/_framework/blazor.webassembly.js:1:3549)
    at Object.Xt [as endInvokeDotNetFromJS] (***********/_framework/blazor.webassembly.js:1:63231)
    at Object.Gt [as invokeJSFromDotNet] (***********/_framework/blazor.webassembly.js:1:62728)
    at Object.Ii (***********/_framework/dotnet.7.0.1.16jbry1adl.js:5:71465)
    at _mono_wasm_invoke_js_blazor (***********/_framework/dotnet.7.0.1.16jbry1adl.js:14:103886)
    at wasm://wasm/00992aee:wasm-function[313]:0x1d4d6
    at wasm://wasm/00992aee:wasm-function[283]:0x1c904
    at wasm://wasm/00992aee:wasm-function[221]:0xdff4
    at wasm://wasm/00992aee:wasm-function[220]:0xce93
    at wasm://wasm/00992aee:wasm-function[8113]:0x1a215b
juho-hanhimaki commented 1 year ago

Seems like a trimmer issue? Workaround below fixes the issues.

Blazor wasm project

  <ItemGroup>
    <TrimmerRootDescriptor Include="TrimmerRootDescriptor.xml" />
  </ItemGroup>

TrimmerRootDescriptor.xml

<?xml version="1.0" encoding="UTF-8" ?>
<linker>
  <assembly fullname="Microsoft.Fast.Components.FluentUI" preserve="all" />
</linker>
vnbaaij commented 1 year ago

Good catch!

I don't think this is something was can/need to add to the library, right? You need to apply this to the project where you are using the library and only when you enable trimming?

juho-hanhimaki commented 1 year ago

Well I would think it's issue with the library since I don't think there is nothing inherently wrong or special with my app. It's a standard blazor wasm app. Sure there is a lot of stuff going on in my project already since I am trying to get a product shipped. So I guess a minimal repro would be needed to try and see if this issue is universal with the library or what might be the root cause of it. Will try to repro if I find the time.

Haven't done anything special with trimming. I think it's on by default in blazor wasm release deployments?

vnbaaij commented 1 year ago

Don't get me wrong, I'm not saying it can't be solved in the library but I just don't know how (yet). I'm not seeing the issues you're seeing in the demo site which is also running on Wasm (on Azure Static Web App). As far as I know trimming is not on by default when publishing. I have not changed anything on the standard publishing workflow.

juho-hanhimaki commented 1 year ago

I'll try to see if I can produce a minimal repro when I find the time. Hopefully we will be wiser after that.

By default, trimming occurs when publishing an app. https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/configure-trimmer?view=aspnetcore-7.0

So the trimming should be on by default unless explicitly disabled. That only makes sense in Blazor since otherwise the size of the app can become prohibitively large.

juho-hanhimaki commented 1 year ago

Well I did the repro. Just a new standard blazor wasm app (with default options) + add library stuff. The issue is there. The menu works normally in debug builds but in the published build it doesn't (clicks cause the exception).

See: https://github.com/juho-hanhimaki/DefaultBlazorWasmApp-fast-blazor

So this is definitely a bug in the library.

Regarding the demo site I am guessing this line prevents trimming and thus the bug doesn't occur there.

https://github.com/microsoft/fast-blazor/blob/43bd5ac6f06d5a31f4b7190810c21f4d20a9e123/examples/FluentUI.Demo.Shared/FluentUI.Demo.Shared.csproj#L9

juho-hanhimaki commented 1 year ago

Perhaps someone from Blazor team could be pinged to take a look? They've likely dealt with similar stuff before.

At least this one had kind of similar exception. https://github.com/dotnet/aspnetcore/issues/25400

I would assume there is a way to make this work nicely without totally making the library untrimmable.

vnbaaij commented 1 year ago

Hi @juho-hanhimaki., As you can see above, I spoke with some people on the team and the issue you are seeing originates from the ASP.NET Core code itself. An issue has been created for that in the aspnetcore repo.

I'm inclined to switch the IsTrimmable to false for the library until that issue is solved. What do you think?

There is a workaround available to use in the meantime by adding an attribute to your code where the ...EventArg classes are being used. For example, in the repo you created change the OnMenuChange method to:

[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(MenuChangeEventArgs))]
    private void OnMenuChange(MenuChangeEventArgs args)
    {
        if (args is not null && args.Value is not null)
            status = $"{args.Value} selected";
    }

And you'll end up with a 69KB trimmed FluentUI library after publishing. Not ideal I know, but we are working on a better solution.

juho-hanhimaki commented 1 year ago

Thanks for getting to the root of this.

I personally am happy with having the workaround until the issue is fixed in the ASP.NET Core. But I can certainly see how some people might run to this issue and be unaware of the workaround existing unless it is properly documented.

vnbaaij commented 1 year ago

There might be a way I can use the attribute in the library itself. Will experiment with it some more tomorrow.

vnbaaij commented 1 year ago

Ok, adding [DynamicDependency] to the (empty) constructor of the component prevents the custom EventArg types to be trimmed. I've added it to all components concerned. You do not have to change your code anymore in the way I described earlier. If you could test with this package and let me know the result, that would be great. I'm also testing it on the demo site now (by setting IsTrimmable=true on FluentUI.Demo.Shared project). Update: Seems to work fine!

juho-hanhimaki commented 1 year ago

I tried the CI build. Now I have the following error in my bigger project:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: ConstructorContainsNullParameterNames, Microsoft.Fast.Components.FluentUI.DesignTokens.Swatch SerializationNotSupportedParentType, System.Object Path: $.
System.NotSupportedException: ConstructorContainsNullParameterNames, Microsoft.Fast.Components.FluentUI.DesignTokens.Swatch SerializationNotSupportedParentType, System.Object Path: $.
 ---> System.NotSupportedException: ConstructorContainsNullParameterNames, Microsoft.Fast.Components.FluentUI.DesignTokens.Swatch
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException_ConstructorContainsNullParameterNames(Type )
   at System.Text.Json.Serialization.Metadata.ReflectionJsonTypeInfo`1[[Microsoft.Fast.Components.FluentUI.DesignTokens.Swatch, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].GetParameterInfoValues()
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure()
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.<EnsureConfigured>g__ConfigureLocked|143_0()
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo.EnsureConfigured()
   at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type , Boolean , Boolean )
   at System.Text.Json.WriteStackFrame.InitializePolymorphicReEntry(Type , JsonSerializerOptions )
   at System.Text.Json.Serialization.JsonConverter.ResolvePolymorphicConverter(Object , JsonTypeInfo , JsonSerializerOptions , WriteStack& )
   at System.Text.Json.Serialization.JsonConverter`1[[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryWrite(Utf8JsonWriter , Object& , JsonSerializerOptions , WriteStack& )
   at System.Text.Json.Serialization.Converters.ArrayConverter`2[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnWriteResume(Utf8JsonWriter , Object[] , JsonSerializerOptions , WriteStack& )
   at System.Text.Json.Serialization.JsonCollectionConverter`2[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnTryWrite(Utf8JsonWriter , Object[] , JsonSerializerOptions , WriteStack& )
   at System.Text.Json.Serialization.JsonConverter`1[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryWrite(Utf8JsonWriter , Object[]& , JsonSerializerOptions , WriteStack& )
   at System.Text.Json.Serialization.JsonConverter`1[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].WriteCore(Utf8JsonWriter , Object[]& , JsonSerializerOptions , WriteStack& )
   Exception_EndOfInnerExceptionStack
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(WriteStack& , NotSupportedException )
   at System.Text.Json.Serialization.JsonConverter`1[[System.Object[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].WriteCore(Utf8JsonWriter , Object[]& , JsonSerializerOptions , WriteStack& )
   at System.Text.Json.JsonSerializer.WriteCore[Object[]](Utf8JsonWriter , Object[]& , JsonTypeInfo`1 )
   at System.Text.Json.JsonSerializer.WriteString[Object[]](Object[]& , JsonTypeInfo`1 )
   at System.Text.Json.JsonSerializer.Serialize[Object[]](Object[] , JsonSerializerOptions )
   at Microsoft.JSInterop.JSRuntime.InvokeAsync[IJSVoidResult](Int64 , String , CancellationToken , Object[] )
   at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__16`1[[Microsoft.JSInterop.Infrastructure.IJSVoidResult, Microsoft.JSInterop, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()
   at Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeVoidAsync(IJSObjectReference , String , Object[] )
   at Microsoft.Fast.Components.FluentUI.DesignTokens.DesignToken`1.<SetValueFor>d__34[[Microsoft.Fast.Components.FluentUI.DesignTokens.Swatch, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at UsesData.Manage.Shared.MainLayout.OnAfterRenderAsync(Boolean firstRender)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task , ComponentState )
juho-hanhimaki commented 1 year ago

The minimal repro with just the menu component works fine now.

vnbaaij commented 1 year ago

1 step forward, 2 steps back...Let's see if we can fix this as well. Can you share the code from UsesData.Manage.Shared.MainLayout.OnAfterRenderAsync(Boolean firstRender)?

juho-hanhimaki commented 1 year ago

@vnbaaij there you go

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _jsModule = await JS.InvokeAsync<IJSObjectReference>("import", "./Shared/MainLayout.razor.js");
            _inDarkMode = await _jsModule!.InvokeAsync<bool>("isDarkMode");

            if (_inDarkMode)
            {
                baseLayerLuminance = StandardLuminance.DarkMode;
            }
            else
            {
                baseLayerLuminance = StandardLuminance.LightMode;
            }

            if (_inDarkMode)
            {
                await AccentBaseColor.SetValueFor(container, "#6264A7".ToSwatch());
            }
            await BaseLayerLuminance.SetValueFor(container, baseLayerLuminance == StandardLuminance.DarkMode ? baseLayerLuminance.GetLuminanceValue() : 0.95f);
            GlobalState.SetLuminance(baseLayerLuminance);
            themeReady = true;
            StateHasChanged();
        }
    }
vnbaaij commented 1 year ago

The error only occurs after trimming? I.e. it works locally in debug mode?

juho-hanhimaki commented 1 year ago

Yep.

vnbaaij commented 1 year ago

I can't really tell from the error but d o you know if it's going wrong on the AccentBaseColor.SetValueFor or the BaseLayerLuminance.SetValueFor

(I;m guessing the AccenBaseColor but wanted to check)

juho-hanhimaki commented 1 year ago

Yup it's the AccentBaseColor one. Wouldn't have noticed this issue if my browser was on light mode. Light mode works fine :)

juho-hanhimaki commented 1 year ago

I suspect that issue might have been there with the nuget version of the package as well. Added that AccentBaseColor line to OnAfterRenderAsync only quite recently after already disabling the trimming. So probably not new behavior in the CI build.

vnbaaij commented 1 year ago

You mean it might not be a trimming issue?

juho-hanhimaki commented 1 year ago

No, it definitely is a trimming issue. Works on non-trimmed build.

Just meant that I don't think it's necessarily new to the build you sent to me. Haven't tested that particular line on the nuget build of the package (with trimming enabled).

vnbaaij commented 1 year ago

Ok, I think I have the code replicated now in my local copy of your minimal repo and publishing as I'm typing this...

Update: Yes, can replicate the error

juho-hanhimaki commented 1 year ago

Added it to the minimal repro as well. Works in debug, exception in published version.

https://github.com/juho-hanhimaki/DefaultBlazorWasmApp-fast-blazor/blob/b807a1c800f2d53786d1a2acb789bd5313254678/DefaultBlazorWasmApp/Client/Shared/MainLayout.razor

vnbaaij commented 1 year ago

Ok, applying the same trick with the attribute on the DesignToken constructor resolved the error in the minimal repo. Please test again with this package

juho-hanhimaki commented 1 year ago

@vnbaaij Tested it and now everything seems to work great. Thanks!

vnbaaij commented 1 year ago

Great! I'll close the issue then. Will release final 2.0 package later today.

saraelsa commented 1 year ago

Hi! I'm getting the same error using FluentSwitch. In this commit it seems that a DynamicDependencyAttribute pointing to CheckboxChangeEventArgs has been added to FluentCheckbox but not to FluentSwitch. Would greatly appreciate a fix—thanks!

vnbaaij commented 1 year ago

This is added for FluentSwitch in version 2.1 which will be released in the coming days

Narvalex commented 5 months ago

Similar issue trying to dismiss FluentDialog by clicking outside the dialog.

Uncaught (in promise) Error: System.InvalidOperationException: There was an error parsing the event arguments. EventId: '5'.
 ---> System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, Microsoft.Fast.Components.FluentUI.DialogEventArgs Path: $ | LineNumber: 0 | BytePositionInLine: 1.
 ---> System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, Microsoft.Fast.Components.FluentUI.DialogEventArgs
   Exception_EndOfInnerExceptionStack
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& , Utf8JsonReader& , NotSupportedException )
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(Type , Utf8JsonReader& , ReadStack& )
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1[[Microsoft.Fast.Components.FluentUI.DialogEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].OnTryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , DialogEventArgs& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.Fast.Components.FluentUI.DialogEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].TryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , DialogEventArgs& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.Fast.Components.FluentUI.DialogEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].ReadCore(Utf8JsonReader& , JsonSerializerOptions , ReadStack& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.Fast.Components.FluentUI.DialogEventArgs, Microsoft.Fast.Components.FluentUI, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]].ReadCoreAsObject(Utf8JsonReader& , JsonSerializerOptions , ReadStack& )
   at System.Text.Json.JsonSerializer.ReadFromSpan[Object](ReadOnlySpan`1 , JsonTypeInfo , Nullable`1 )
   at System.Text.Json.JsonSerializer.ReadFromSpan[Object](ReadOnlySpan`1 , JsonTypeInfo )
   at System.Text.Json.JsonSerializer.Deserialize(String , Type , JsonSerializerOptions )
   at Microsoft.AspNetCore.Components.Web.WebEventData.ParseEventArgsJson(Renderer , JsonSerializerOptions , UInt64 , String , JsonElement )
   Exception_EndOfInnerExceptionStack
   at Microsoft.AspNetCore.Components.Web.WebEventData.ParseEventArgsJson(Renderer , JsonSerializerOptions , UInt64 , String , JsonElement )
   at Microsoft.AspNetCore.Components.Web.WebEventData.Parse(Renderer , JsonSerializerOptions , WebEventDescriptor , JsonElement )
   at Microsoft.AspNetCore.Components.Web.WebEventData.Parse(Renderer , JsonSerializerOptions , JsonElement , JsonElement )
   at Microsoft.AspNetCore.Components.RenderTree.WebRenderer.WebRendererInteropMethods.DispatchEventAsync(JsonElement eventDescriptor, JsonElement eventArgs)
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.InvokeSynchronously(JSRuntime , DotNetInvocationInfo& , IDotNetObjectReference , String )
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(JSRuntime , DotNetInvocationInfo , String )
    at Object.endInvokeDotNetFromJS (***********/_framework/blazor.webassembly.js:1:3549)
    at Object.Xt [as endInvokeDotNetFromJS] (***********/_framework/blazor.webassembly.js:1:63231)
    at Object.Gt [as invokeJSFromDotNet] (***********/_framework/blazor.webassembly.js:1:62728)
    at Object.Ii (***********/_framework/dotnet.7.0.1.16jbry1adl.js:5:71465)
    at _mono_wasm_invoke_js_blazor (***********/_framework/dotnet.7.0.1.16jbry1adl.js:14:103886)
    at wasm://wasm/00992aee:wasm-function[313]:0x1d4d6
    at wasm://wasm/00992aee:wasm-function[283]:0x1c904
    at wasm://wasm/00992aee:wasm-function[221]:0xdff4
    at wasm://wasm/00992aee:wasm-function[220]:0xce93
    at wasm://wasm/00992aee:wasm-function[8113]:0x1a215b

I'm still having this issue when dismissing dialog and panels by clicking the overlay. But only when using with the Dialog Service. With Dialogs that do not use the DialogService there is no problem on dismissing by clicking the overlay. Using version 4.2.1 in Azure Static Web Apps. Should I disable the trimming?

dvoituron commented 5 months ago

You probably still have references to an older library, as the error message indicates version 2.0.0.0 Microsoft.Fast.Components.FluentUI, Version=2.0.0.0 and refers to .NET 7 _framework/dotnet.7.0.1, whereas FluentUI-Blazor lib 4.0 supports only .NET8.

Narvalex commented 5 months ago

@dvoituron I was just quoting @juho-hanhimaki error that he had when clicking the overlay to dismiss the dialog. Bellow is my own error. And by the day, the FluentDialog constructor does not have the decorator that is mentioned in this thread as the workaround solution. Is there a reason for that?

blazor.webassembly.js:1  Uncaught (in promise) Error: System.InvalidOperationException: There was an error parsing the event arguments. EventId: '8'.
 ---> System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, Microsoft.FluentUI.AspNetCore.Components.DialogEventArgs Path: $ | LineNumber: 0 | BytePositionInLine: 1.
 ---> System.NotSupportedException: DeserializeNoConstructor, JsonConstructorAttribute, Microsoft.FluentUI.AspNetCore.Components.DialogEventArgs
   Exception_EndOfInnerExceptionStack
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack& , Utf8JsonReader& , NotSupportedException )
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(Type , Utf8JsonReader& , ReadStack& )
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1[[Microsoft.FluentUI.AspNetCore.Components.DialogEventArgs, Microsoft.FluentUI.AspNetCore.Components, Version=4.2.1.23354, Culture=neutral, PublicKeyToken=null]].OnTryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , DialogEventArgs& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.FluentUI.AspNetCore.Components.DialogEventArgs, Microsoft.FluentUI.AspNetCore.Components, Version=4.2.1.23354, Culture=neutral, PublicKeyToken=null]].TryRead(Utf8JsonReader& , Type , JsonSerializerOptions , ReadStack& , DialogEventArgs& , Boolean& )
   at System.Text.Json.Serialization.JsonConverter`1[[Microsoft.FluentUI.AspNetCore.Components.DialogEventArgs, Microsoft.FluentUI.AspNetCore.Components, Version=4.2.1.23354, Culture=neutral, PublicKeyToken=null]].ReadCore(Utf8JsonReader& , JsonSerializerOptions , ReadStack& )
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1[[Microsoft.FluentUI.AspNetCore.Components.DialogEventArgs, Microsoft.FluentUI.AspNetCore.Components, Version=4.2.1.23354, Culture=neutral, PublicKeyToken=null]].Deserialize(Utf8JsonReader& , ReadStack& )
   at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1[[Microsoft.FluentUI.AspNetCore.Components.DialogEventArgs, Microsoft.FluentUI.AspNetCore.Components, Version=4.2.1.23354, Culture=neutral, PublicKeyToken=null]].DeserializeAsObject(Utf8JsonReader& , ReadStack& )
   at System.Text.Json.JsonSerializer.ReadFromSpanAsObject(ReadOnlySpan`1 , JsonTypeInfo , Nullable`1 )
   at System.Text.Json.JsonSerializer.ReadFromSpanAsObject(ReadOnlySpan`1 , JsonTypeInfo )
   at System.Text.Json.JsonSerializer.Deserialize(String , Type , JsonSerializerOptions )
   at Microsoft.AspNetCore.Components.Web.WebEventData.ParseEventArgsJson(Renderer , JsonSerializerOptions , UInt64 , String , JsonElement )
   Exception_EndOfInnerExceptionStack
   at Microsoft.AspNetCore.Components.Web.WebEventData.ParseEventArgsJson(Renderer , JsonSerializerOptions , UInt64 , String , JsonElement )
   at Microsoft.AspNetCore.Components.Web.WebEventData.Parse(Renderer , JsonSerializerOptions , WebEventDescriptor , JsonElement )
   at Microsoft.AspNetCore.Components.Web.WebEventData.Parse(Renderer , JsonSerializerOptions , JsonElement , JsonElement )
   at Microsoft.AspNetCore.Components.RenderTree.WebRenderer.WebRendererInteropMethods.DispatchEventAsync(JsonElement eventDescriptor, JsonElement eventArgs)
   at System.Object.InvokeStub_WebRendererInteropMethods.DispatchEventAsync(Object , Span`1 )
   at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object , BindingFlags , Binder , Object[] , CultureInfo )
--- End of stack trace from previous location ---
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.InvokeSynchronously(JSRuntime , DotNetInvocationInfo& , IDotNetObjectReference , String )
   at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(JSRuntime , DotNetInvocationInfo , String )
    at g.endInvokeDotNetFromJS (https://green-grass-0cd81780f.2.azurestaticapps.net/_framework/blazor.webassembly.js:1:3136)
    at Object.gn [as endInvokeDotNetFromJS] (https://green-grass-0cd81780f.2.azurestaticapps.net/_framework/blazor.webassembly.js:1:58655)
    at https://green-grass-0cd81780f.2.azurestaticapps.net/_framework/dotnet.runtime.8.0.0.2kk3sju48u.js:3:177853
    at Ul (https://green-grass-0cd81780f.2.azurestaticapps.net/_framework/dotnet.runtime.8.0.0.2kk3sju48u.js:3:178687)
    at wasm://wasm/00a66bbe:wasm-function[208]:0x187ce
    at wasm://wasm/00a66bbe:wasm-function[103]:0x14c9c
    at wasm://wasm/00a66bbe:wasm-function[96]:0x80c2
    at wasm://wasm/00a66bbe:wasm-function[130]:0x15eb0
    at wasm://wasm/00a66bbe:wasm-function[2812]:0xc531c
    at wasm://wasm/00a66bbe:wasm-function[2186]:0x9ce04
dvoituron commented 5 months ago

@Narvalex This problem seems to be due to an invalid deserialization of the DialogEventArgs class. Are you using a class inherited from this class? Or can you add this line to your code to check whether the Trimming process has removed this class?

var temp = new DialogEventArgs() { Id = "1", Reason = "Unknown" };
Narvalex commented 5 months ago

@dvoituron I was just using the Dialog in the SWA and the dismiss did not work. But after instatiating somewhere a DialogEventArgs object, the trimmer didnot "trimmed out" it. It worked! Thanks a lot!

dvoituron commented 5 months ago

@dvoituron I was just using the Dialog in the SWA and the dismiss did not work. But after instatiating somewhere a DialogEventArgs object, the trimmer didnot "trimmed out" it. It worked! Thanks a lot!

Ok. Thanks. We will add this solution (part of code) in our lib for the next Release.