提供的动态组件的 blazor validationMessage 表达式包含不支持的 InstanceMethodCallExpression1

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

我正在 blazor 中构建一些动态表单生成器,我对这部分有疑问

 @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()_@prop.Name">@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;
}

所以我得到这个错误

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

因为

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

有没有其他方法可以做到这一点 'properly'?或通过建设者? 谢谢和问候!

我认为有错别字:

@(()=> @prop.GetValue(DataContext)) 应该是 @(()=> prop.GetValue(DataContext)) (第二个@符号在这里不好)

你能试试吗?

ValidationMessage 需要一个可以分解以获得 属性 名称的表达式。它使用从级联 EditContext 获得的 ModelFor 获得的 属性 来查询 EditContext 上的 ValidationMessageStore 以获取任何消息针对 Model/Property.

记录

您收到错误消息是因为 For 的格式不正确。

这就是构建动态表单的问题:您还需要构建与之配套的基础结构。

这是 Blazor 存储库中的相关代码 - https://github.com/dotnet/aspnetcore/blob/66104a801c5692bb2da63915ad877d641c45cd42/src/Components/Forms/src/FieldIdentifier.cs#L91(祝你好运!)

好吧,我终于在某处找到了类似的东西并稍作修改,它就可以工作了 所以对于未来的搜索者:

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

在代码中:

 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();


   };

问候