Aspnetcore: Binding to events to a component that inherits from a c# class broke in 0.4.0

Created on 8 Jun 2018  路  19Comments  路  Source: dotnet/aspnetcore

The following worked in 0.3.0:

DynamicElement is defined here: https://github.com/aspnet/Blazor/blob/stevesa/bootstrap-components-library/src/Microsoft.AspNetCore.Blazor.Bootstrap/DynamicElement.cs

<DynamicElement onclick="@onclick" ...>...</DynamicElement>

@functions {
  [Parameter] private Action onclick { get; set; }
}

in 0.4.0 an error on build:

Argument 1: cannot convert from 'System.MulticastDelegate' to 'string'
area-blazor

Most helpful comment

This should be fixed now in the dev branch

All 19 comments

I had the same error on one of my own component, actually it was because an other subcomponent was still using the public accessor syntax instead of the private one with the [Parameter] attribute.

As i don't use the DynamicElement component, i have no clue for you.

Not 100% sure but this seems to be the problematic line in .g.cs files:

builder.AddAttribute(3, "onclick", Microsoft.AspNetCore.Blazor.Components.RuntimeHelpers.TypeCheck<System.String>(Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(onclick)));

It should be:

builder.AddAttribute(1, "onclick", Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(onclick));

I don't have took a look but maybe the OnClick property attribute on the base component may not have upgraded to the new signature type ?

@SteveSandersonMS Thoughts on this one?

I haven't investigated it yet, but cc @rynowak in case it's immediately obvious to him.

@rynowak Any thoughts on this issue? I am stuck on Blazor 0.3.0 because I can't upgrade :(

What if you try Action<UIMouseEventArgs>>?

@rynowak Same error.

Here is a repo with the error: https://github.com/chanan/Blazor4Test

I have cloned your project and for me Blazor4Test compiles and works as expected.

  • VS 15.7.3
  • Blazor 0.4.0
  • .NET Core 2.1 (dotnet --version displays 2.1.300)

Your project looks like default starting project without any changes. Am I missing something?

Oops, forgot to push. Sorry about that. The issue is on ButtonTest.cshtml

@rynowak In Blazor 0.4.0 you have added this file:

Blazor\src\Microsoft.AspNetCore.Blazor\Components\RuntimeHelpers.cs

with this function inside
```C#
public static T TypeCheck(T value) => value;

I don't know what code was generated in Blazor 0.3.0 but now in

Blazor4Test\objDebug\netstandard2.0\Pages\ButtonTest.g.cs

file we have something like this:
```C#
builder.AddAttribute(3, "OnClick", Microsoft.AspNetCore.Blazor.Components.RuntimeHelpers.TypeCheck<System.String>(Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>(OnClick)));

and that is why we get

Argument 1: cannot convert from 'System.MulticastDelegate' to 'string'

Maybe @SteveSandersonMS will be able to help here (author of DynamicElement).

Assigning myself to look into this.

I think I'll have to understand a bit more about the design of dynamic element. What's going on is that the type checking expects this parameter to be a string, even though it's obviously not.

It's possible that I messed up the type checking for extra parameters by type checking them as strings, when they could be all kinds of things.

I have applied a few changes to DynamicElement as suggested by @Daddoon

I had the same error on one of my own component, actually it was because an other subcomponent was still using the public accessor syntax instead of the private one with the [Parameter] attribute.

```c#
- public string TagName { get; set; }
+ [Parameter]
+ private string TagName { get; set; }

  • public Action OnClick { get; set; }
  • [Parameter]
  • private Action OnClick { get; set; }

    /// <summary>
    /// Gets or sets the attributes to render.
    /// </summary>
    
  • public IReadOnlyDictionary Attributes
  • [Parameter]
  • private IDictionary Attributes
I have also removed this
```c#
public Action<UIMouseEventArgs> OnClick { get; set; }

from BootstrapComponentBase.
Now I'm able to compile and run your test application, but there are at least two problems:

  • button is not rendered correctly (probably ChildContent is not rendered inside button)
  • I see runtime exception in browser console when I click on the button (SyntaxError: unexpected token: numeric literal)

@rynowak Temporarily it looks that it is not your fault, but please don't close this yet. It is possible that there are some other bugs somewhere in Blazor or in @chanan 's source code. Unfortunately it is 3:30am in Poland and I have to go to bed 馃槳

The problem with that solution is that:

  1. You would need to provide properties for each possible attribute
  2. You would need to then throw an unsupported exception for those properties that don't actually make sense base on tag name.

While doable, no ideal.

But also, as you say at the end, it still doesnt work right :)

So, I would say, yes this is still an issue due to the fact that the purposed workaround still doesn't fully work.

@rynowak Is this likely to be fixed soon? I am really stuck with this in both https://github.com/chanan/BlazorStrap and to a bit lesser extant on https://github.com/chanan/Blazorous

As a temporary workaround, you may try to change the private value via reflection + StateHasChanged ? But it's a very quirck solution...

I'll take a look at this today

OK, I've been able to reproduce this, looking at a fix that will drop the type check any type an attribute is 'weakly typed'.

This should be fixed now in the dev branch

Was this page helpful?
0 / 5 - 0 ratings