首页 > 解决方案 > Blazor 动态字段和带有验证/验证器的 ASP.Net.Core

问题描述

我试图编写一个 Blazor 应用程序(从服务器端启动),它可以动态地创建带有验证的表单字段。我喜欢 Razor 附带的绑定到模型的验证/验证器,但我不知道如何为动态创建的字段(也就是无模型)执行此操作。

这就是我所拥有的。我非常感谢一些指导。
谢谢!杰森

启动.cs

...
public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();

            services.AddSingleton<DynamicControlService>();
        }
...

控件类型.cs

namespace DynamicContent
{
    public enum ControlTypes
    {
        Text                = 1,
        Date                = 2,
        DateTime            = 3,
        Time                = 4, 
        SingleSelect        = 5, // DropdownList
        MultiSelect         = 6,
        Boolean             = 7, // Checkbox or Slide
        Email               = 8,
        RadioButtonList     = 9
    }
}

控制细节.cs

namespace DynamicContent
{
    public class ControlDetails
    {
        public string ID { get; set; }
        public string FieldName { get; set; }
        public ControlTypes Type { get; set; } = ControlTypes.Text;
        public string Label { get; set; }
        public bool IsRequired { get; set; }
        public bool IsReadOnly { get; set; } = false;
        public string Tooltip { get; set; } // ToDo: Default to Label (if not set)
        public string Placeholder { get; set; }
        public string Min { get; set; } = string.Empty;
        public string Max { get; set; } = string.Empty;
    }
}

动态控制服务.cs

using System.Collections.Generic;

namespace DynamicContent
{
    public class DynamicControlService
    {
        public List<ControlDetails> GetControls()
        {
// Eventually this will pull from a database 
            var result = new List<ControlDetails>();

            result.Add(new ControlDetails { FieldName = "firstName", Label = "First Name", IsRequired = true });
            result.Add(new ControlDetails { FieldName = "lastName", Label = "Last Name", IsRequired = true });
            result.Add(new ControlDetails { FieldName = "birthDate", Type = ControlTypes.Date, Label = "Birth Date",
                IsRequired = false, Tooltip = "Please enter Birth Date in mm/dd/yyyy format" });

            return result;
        }
    }
}

反剃刀

@page "/counter"
@inject DynamicControlService _controlService

<form>
    @foreach (var control in ControlList)
    {
        <div class="form-group">

            <!-- Label -->
            <label asp-for=@(control.FieldName) class="label-control">
                @(control.Label) @if (control.IsRequired)
                {<b> *</b>}
            </label>

            <!-- Input field -->
            @switch (control.Type)
            {
                case ControlTypes.Text:
                    <input type="text" id="@control.ID" class="form-control" asp-for=@(control.FieldName)
                            @bind-value="@Values[control.Label]" required="@control.IsRequired" />
                    break;

                case ControlTypes.Email:
                    <input type="email" id="@control.ID" class="form-control" value="@Values[control.Label]"
                            required="@control.IsRequired" />
                    break;

                case ControlTypes.Date:
                    <input type="date" id="@control.ID" class="form-control" value="@Values[control.Label]"
                            required="@control.IsRequired" @onchange="@(a => ValueChanged(a, control.Label))"
                            min="1900-01-01" max="2999-12-31"/>
                    break;
            }


            <!-- Validation Message -->
            <span asp-validation-for=@(control.FieldName) class="text-danger"></span>
        </div>

        <!-- @@((MarkupString)buildInputField(control)) -->
    }

    <p />
    <button @onclick="OnClick" type="submit">Submit</button>
</form>

@code
{
    private List<ControlDetails> ControlList;
    private Dictionary<string, string> Values;

    // ToDo: protected override async Task OnInitializedAsync()
    protected override void OnInitialized()
    {
        base.OnInitialized();

        ControlList = _controlService.GetControls();
        Values = ControlList.ToDictionary(c => c.Label, c => "");
    }

    void ValueChanged(ChangeEventArgs a, string label)
    {
        // ToDo: force date to be within min/max (e.g. typing 9999 is not valid given max of 2999) 
        Values[label] = a.Value.ToString();
    }

    string GetValue(string label)
    {
        return Values[label];
    }

    private void OnClick(MouseEventArgs e)
    {
        // send your Values
    }

    // ToDo: Build a method for creating a field with label support 
    private string buildInputField(ControlDetails control)
    {
        return "";
        /*
        string inputField = $"<input type=\"{control.Type}\" id=\"@control.ID\" " +
                "class=\"form-control\" asp-for=@(control.FieldName) " +
                "@bind-value=\"@Values[control.Label]\" required=\"@control.IsRequired";

        inputField += "/>";

        return inputField;
        */
    }
}

标签: c#asp.net-corerazorblazorblazor-server-side

解决方案


推荐阅读