【问题标题】:How to provide ValidationMessage For with property generated at runtime?如何为运行时生成的属性提供 ValidationMessage For?
【发布时间】:2023-02-22 05:19:54
【问题描述】:

我在运行时生成一个对象以用作 EditForm 模型。验证工作正常,但我不确定如何设置需要 Expression<Func<object>> 的 ValidationMessage 组件。

我想通过反射为它提供一个属性。像这样:

<ValidationMessage For="@(() => modelType.GetProperty("MyString").GetValue(model))" />

如何从运行时生成的对象属性中获取表达式?

编辑:

这是我的代码:

<EditForm Model="@GeneratedModel" OnInvalidSubmit="@HandleInvalidSubmit" OnValidSubmit="@OnValidSubmit">
    <DataAnnotationsValidator />
    <input @bind="TestPropBind" type="text" />
    <ValidationMessage For="@ValidationFor" />
</EditForm>

@code
{
    private object GeneratedModel { get; set; }

    private string TestPropBind
    {
        get
        {
            PropertyInfo? propertyInfo = GeneratedModel.GetType().GetProperty("Test");
            MethodInfo? getMethod = propertyInfo.GetGetMethod();
            return getMethod.Invoke(GeneratedModel, new object?[0]) as string;
        }
        set
        {
            PropertyInfo? propertyInfo = GeneratedModel.GetType().GetProperty("Test");
            MethodInfo? setMethod = propertyInfo.GetSetMethod();
            setMethod.Invoke(GeneratedModel, new[] { value });
        }
    }

    protected override void OnInitialized()
    {
    //GeneratedModel created and instantiated here at runtime
    }
}

【问题讨论】:

  • 你有机会检查这个吗? ASP.NET Core Blazor forms and input components
  • AFAIK 你不能。但是你能展示更多你的代码吗?至少整个 EditForm 部分。
  • @SalehYusefnejad 我更新了它
  • 我建议为那些共享道具使用通用组件和基类/接口。 (基本没有反映)

标签: c# .net validation blazor blazor-editform


【解决方案1】:

ValidationMessage 是一个相当简单的组件。在内部,它使用 For 构建一个 FieldIdentifier 对象,它使用该对象在 EditContext's 验证消息存储中查找验证消息。

您可以通过构建您自己的以FieldIdentifier作为参数的ValidationMessage来缩短整个反射/ExpressionBuilder过程:

@foreach (var message in editContext.GetValidationMessages(Identifier))
{
    <div class="validation-message" @attributes=this.AdditionalAttributes>
        @message
    </div>
}

@code {
    [CascadingParameter] private EditContext editContext { get; set; } = default!;
    [Parameter, EditorRequired] public FieldIdentifier Identifier { get; set; } = new FieldIdentifier();
    [Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object>? AdditionalAttributes { get; set; }

    protected override void OnInitialized()
    {
        ArgumentNullException.ThrowIfNull(editContext);
    }
}

您的演示页面:

@page "/"
@using System.ComponentModel.DataAnnotations;
@using System.Reflection;

<PageTitle>Index</PageTitle>

<EditForm Model=this.model OnValidSubmit=this.OnValidSubmit >
    <DataAnnotationsValidator/>
    <div class="mb-3">
        <span class="form-label">Value</span>
        <input class="form-control" @bind=this.model.Value />
        <MyValidationMessage Identifier=TestPropIdentifier  />
    </div>
    <div class="mb-3">
        <button class="btn btn-primary">Submit</button>
    </div>
</EditForm>

@code {
    private Model model = new();

    private FieldIdentifier TestPropIdentifier => new FieldIdentifier(model, "Value");

    private string TestPropBind
    {
        get
        {
            PropertyInfo? propertyInfo = model.GetType().GetProperty("Value");
            MethodInfo? getMethod = propertyInfo?.GetGetMethod();
           return getMethod?.Invoke(model, new object?[0]) as string ?? string.Empty ;
        }
        set
        {
            PropertyInfo? propertyInfo = model.GetType().GetProperty("Value");
            MethodInfo? setMethod = propertyInfo?.GetSetMethod();
            setMethod?.Invoke(model, new[] { value });
        }
    }

    private void OnValidSubmit()
    {
    }

    public class Model
    {
        [Required]
        public string? Value { get; set; }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-16
    • 2014-11-06
    相关资源
    最近更新 更多