.net core 动态属性和子模型未绑定

.net core 动态属性和子模型未绑定,.net-core,blazor,.net Core,Blazor,我想使用Blazor构建动态表单 这是我的示例组件 @page "/customform" @using System.Dynamic @using System.Text.Json @inject IJSRuntime JSRuntime; <div class="card m-3"> <h4 class="card-header">Blazor WebA

我想使用Blazor构建动态表单

这是我的示例组件

    @page "/customform"

    @using System.Dynamic
    @using System.Text.Json
 
    @inject IJSRuntime JSRuntime;

    <div class="card m-3">
    <h4 class="card-header">Blazor WebAssembly Form Validation Example</h4>
    <div class="card-body">
        <EditForm EditContext="@editContext"
                  OnValidSubmit="HandleValidSubmit">
            <DataAnnotationsValidator></DataAnnotationsValidator>
           
            @foreach (var field in Model.Fields)
        {

            <div class="form-group">
                <label>@field.Name</label>
                <input @bind-value="field.Value" class="form-control" />
                <ValidationMessage For="(()=> field.Value)" />
                <ValidationMessage For="(()=> field.Name)" />
                <ValidationMessage For="(()=> field)" />

            </div>

        }
            <div class="form-group">
                <label>Address</label>
                <input @bind-value="Model.Address" class="form-control" />
                <ValidationMessage For="()=> Model.Address" />

            </div>
            <div class="form-group">
                <label>Child</label>
                <input @bind-value="Model.ChildModel.ChildName" class="form-control" />
                <ValidationMessage For="()=> Model.ChildModel.ChildName" />

            </div>
            <div class="text-left">
                <button class="btn btn-primary" type="submit">Submit</button>
            </div>

        </EditForm>
    </div>
         </div>

      @code{

    private SampleModel Model = new SampleModel();
    private EditContext editContext;
    private ValidationMessageStore _messageStore;

    protected override void OnInitialized()
    {

        editContext = new EditContext(Model);
        editContext.OnValidationRequested += ValidationRequested;
        _messageStore = new ValidationMessageStore(editContext);      
    }

    private void HandleValidSubmit(EditContext context)
    {
        var modelJson = JsonSerializer.Serialize(context.Model, new JsonSerializerOptions { WriteIndented = true });
        JSRuntime.InvokeVoidAsync("alert", $"SUCCESS!! :-)\n\n{modelJson}");
       
    }

    async void ValidationRequested(object sender, ValidationRequestedEventArgs args)
    {
        _messageStore.Add(editContext.Field("FirstName"), "Test");
        _messageStore.Add(editContext.Field("Address"), "Invalid Address");
        _messageStore.Add(editContext.Field("ChildModel.ChildName"), "Invalid Child Name");
        editContext.NotifyValidationStateChanged();
    }

    

    public class SampleModel
    {

        public string Address { get; set; }

        public ChildModel ChildModel { get; set; }
        public List<Field> Fields { get; set; }
        public SampleModel()
        {
            this.ChildModel = new ChildModel();
            this.Fields = new List<Field>();
            this.Fields.Add(new Field()
            {
                Name = "FirstName",
                Value = "",
                ControlType = ControlType.Input
            });
            this.Fields.Add(new Field()
            {
                Name = "LastName",
                Value = "",
                ControlType = ControlType.Input
            });
        }
    }

    public class ChildModel
    {
        public string ChildName { get; set; }
    }

    public enum ControlType
    {
        Input
    }

    public class Field
    {
        public string Value { get; set; }
        public string Name { get; set; }
        public string DisplayName { get; set; }
        public ControlType ControlType { get; set; }


    }

    
}
@page”/customform
@使用系统。动态
@使用System.Text.Json
@注入IJSRuntime JSRuntime;
Blazor WebAssembly表单验证示例
@foreach(Model.Fields中的var字段)
{
@字段名
}
地址
小孩
提交
@代码{
私有SampleModel模型=新SampleModel();
私有编辑上下文编辑上下文;
私有验证messageStore\u messageStore;
受保护的覆盖无效OnInitialized()
{
editContext=新的editContext(模型);
editContext.OnValidationRequested+=ValidationRequested;
_messageStore=新的ValidationMessageStore(编辑上下文);
}
私有void HandleValidSubmit(EditContext上下文)
{
var modelJson=JsonSerializer.Serialize(context.Model,新的JsonSerializerOptions{writeindended=true});
JSRuntime.InvokeVoidAsync(“警报”,“$”成功!!:-)\n\n{modelJson});
}
异步void ValidationRequested(对象发送方,ValidationRequestedEventArgs args)
{
_Add(editContext.Field(“FirstName”),“Test”);
_添加(editContext.Field(“地址”),“无效地址”);
_Add(editContext.Field(“ChildModel.ChildName”),“无效的子名称”);
editContext.NotifyValidationStateChanged();
}
公共类抽样模型
{
公共字符串地址{get;set;}
公共ChildModel ChildModel{get;set;}
公共列表字段{get;set;}
公共样本模型()
{
this.ChildModel=新的ChildModel();
this.Fields=新列表();
this.Fields.Add(新字段()
{
Name=“FirstName”,
Value=“”,
ControlType=ControlType.Input
});
this.Fields.Add(新字段()
{
Name=“LastName”,
Value=“”,
ControlType=ControlType.Input
});
}
}
公共类儿童模型
{
公共字符串ChildName{get;set;}
}
公共枚举控制类型
{
输入
}
公共类字段
{
公共字符串值{get;set;}
公共字符串名称{get;set;}
公共字符串DisplayName{get;set;}
公共控制类型控制类型{get;set;}
}
}
目前我面临的问题太多了

  • 如果我使用For lookup而不是For each,它将不起作用
  • ChildModel似乎已绑定,但其验证不起作用
  • 基于字段动态生成的集合控件不显示验证
  • SimpleModel显示验证中的唯一地址

  • 这方面有什么建议或帮助吗?

    你的个人资料表明你知道自己在做什么,所以我会保持简洁

    您的
    for
    循环需要如下所示。在循环中设置一个本地“索引”变量,以链接控件。如果没有,则它们指向
    i的最后一个值
    ——在本例中为
    超出范围的第2个值
    !razor代码由razor builder转换为cs文件。您可以看到在obj文件夹结构-obj\Debug\net5.0\Razor\Pages中生成的c#文件。注意,验证消息的链接

    (变量i=0;i 现在是消息验证存储。这是我重写的
    验证请求
    。注意,我正在创建一个
    FieldIdentifier
    ,这是正确的方法。“地址”之所以有效,是因为它是
    EditContext.Model
    的一个属性。如果
    ValidationMessage
    未显示您预期的消息,则该消息不是未生成,就是
    FieldIdentifier
    ValidationMessage
    字段不匹配。这会让你参与到你所参与的任何项目中——如果没有添加注释以澄清:-)

    void ValidationRequested(对象发送方,ValidationRequestedEventArgs args)
    {
    _messageStore.Clear();
    _添加(新字段标识符(Model.Fields[0],“Value”),“FirstName验证消息”);
    _messageStore.Add(新字段标识符(Model.Fields[1],“Value”),“姓氏验证消息”);
    _Add(editContext.Field(“FirstName”),“Test”);
    _添加(editContext.Field(“地址”),“无效地址”);
    _Add(editContext.Field(“ChildModel.ChildName”),“无效的子名称”);
    editContext.NotifyValidationStateChanged();
    }
    

    如果您对验证感兴趣,并且希望获得比基本的开箱即用验证更多的东西,那么我的几篇文章可能会为您提供信息,或者如果您搜索的话,这里有Chris Sainty的Fluent Validation版本。

    您的个人资料表明您知道自己在做什么,因此我将保持简洁

    您的
    for
    循环需要如下所示。在循环中设置一个本地“索引”变量,以链接控件。如果没有,则它们指向
    i的最后一个值
    ——在本例中为
    超出范围的第2个值
    !razor代码由razor builder转换为cs文件。您可以看到在obj文件夹结构-obj\Debug\net5.0\Razor\Pages中生成的c#文件。注意,验证消息的链接

    (变量i=0;i