提供的动态组件的 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
获得的 Model
和 For
获得的 属性 来查询 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();
};
问候
我正在 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
获得的 Model
和 For
获得的 属性 来查询 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();
};
问候