'blazor validationMessage of dynamic component provided expression contains a InstanceMethodCallExpression1 which is not supported

im building some dynamic form generator in blazor and i have issue with this part

 @using Microsoft.AspNetCore.Components.CompilerServices
 @using System.Text.Json
 @using System.ComponentModel.DataAnnotations
 @typeparam Type


<EditForm Model="@DataContext" OnValidSubmit="OnValidSubmit">
<DataAnnotationsValidator/>
 @foreach (var prop in  typeof(Type).GetProperties())
{
    <div class="mb-3">
     <label for= "@this.idform.ToString()[email protected]">@Label(@prop.Name) : </label> 
     
        @CreateStringComponent(@prop.Name)

        @if (ShowValidationUnderField)
        {
                   <ValidationMessage For = "@(()=> @prop.GetValue(DataContext))"></ValidationMessage>

        }
      </div>
      
    
}

@code {
[Parameter] public Type? DataContext { get; set; } 

[Parameter] 
public EventCallback<Type> OnValidSubmitCallback { get; set; }

[Parameter]
public bool ShowValidationSummary { get; set; } = false;

[Parameter]
public bool ShowValidationUnderField { get; set; } = true;
}

so i get this error

'provided expression contains a InstanceMethodCallExpression1 which is not supported.'

its because of

@(()=> @prop.GetValue(DataContext))

is there any other way that i can do that 'properly' ? or via builder? thanks and regards !



Solution 1:[1]

ok i finaly found something similar somwhere and modified a bit and it works so for future searchers:

@if (ShowValidationUnderField)
{
     @FieldValidationTemplate(@prop.Name)
}

and in code:

 public RenderFragment? FieldValidationTemplate(string fld) => builder =>
   {

       PropertyInfo? propInfoValue = typeof(ContextType).GetProperty(fld);

       var access = Expression.Property(Expression.Constant(DataContext, typeof(ContextType)), propInfoValue!);
       var lambda = Expression.Lambda(typeof(Func<>).MakeGenericType(propInfoValue!.PropertyType), access);

       builder.OpenComponent(0, typeof(ValidationMessage<>).MakeGenericType(propInfoValue!.PropertyType));
       builder.AddAttribute(1, "For", lambda);
       builder.CloseComponent();


   };

regards

Solution 2:[2]

I think there is a typo:

@(()=> @prop.GetValue(DataContext)) should be @(()=> prop.GetValue(DataContext)) (the second @ symbol is not good here)

Can you try it please?

Solution 3:[3]

ValidationMessage expects an expression that it can decompose to get the property name. It uses the Model it gets from the cascaded EditContext and the property from the For to query the ValidationMessageStore on the EditContext for any messages logged against the Model/Property.

You get the error because the For isn't in the correct format.

That's the problem with building Dynamic forms: you also need to build the infrastructure that goes with them.

This is the relevant code in the Blazor repository - https://github.com/dotnet/aspnetcore/blob/66104a801c5692bb2da63915ad877d641c45cd42/src/Components/Forms/src/FieldIdentifier.cs#L91 (good luck!)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 d00lar
Solution 2 Dylan Barquilla
Solution 3