ASP.NET Blazor 需要使用 InputSelect 进行验证

Sti*_*gar 7 c# asp.net blazor blazor-server-side

我正在尝试让Required 属性与InputSelect 一起使用,但验证在Blazor Server 中不起作用。该表格无需选择即可提交。有趣的是,当模型属性可为空时它会起作用。在 .NET 5.0 之前,它不适用于可空类型,因为 InputSelect 不支持它们。然而,我想要一个不可为 null 的必需属性,因为我想将 API 中的 dto 重用为模型,而且它在逻辑上是错误的。

在此输入图像描述

public class SomeModel
{
    [Required]
    public string SomeString { get; set; }

    [Required]
    public SomeEnum SomeEnum { get; set; }

    [Required]
    public SomeEnum? SomeNullableEnum { get; set; }

    [Required]
    public int SomeInt { get; set; }

    [Required]
    public int? SomeNullableInt { get; set; }
}

public enum SomeEnum
{
    A = 1,
    B = 2
}
Run Code Online (Sandbox Code Playgroud)

这一页

@page "/testrequired"
@using TestNET5BlazorServerApp.Data;


<EditForm Model="Model" OnValidSubmit="Submit">

    <DataAnnotationsValidator />
    <ValidationSummary />

    String:
    <br />
    <InputText @bind-Value="Model.SomeString" />
    <br />
    <br />
    Enum:
    <br />
    <InputSelect @bind-Value="Model.SomeEnum">
        <option value="">Select Enum</option>
        <option value="@SomeEnum.A">@SomeEnum.A</option>
        <option value="@SomeEnum.B">@SomeEnum.B</option>
    </InputSelect>
    <br />
    <br />

    Nullable Enum:
    <br />
    <InputSelect @bind-Value="Model.SomeNullableEnum">
        <option>Select Nullable Enum</option>
        <option value="@SomeEnum.A">@SomeEnum.A</option>
        <option value="@SomeEnum.B">@SomeEnum.B</option>
    </InputSelect>
    <br />
    <br />

    Int:
    <br />
    <InputSelect @bind-Value="Model.SomeInt">
        <option>Select Int</option>
        <option value="1">1</option>
        <option value="2">2</option>
    </InputSelect>
    <br />
    <br />

    Nullable Int:
    <br />
    <InputSelect @bind-Value="Model.SomeNullableInt">
        <option>Select Nullable Int</option>
        <option value="1">1</option>
        <option value="2">2</option>
    </InputSelect>
    <br />
    <br />

    <button type="submit">Save</button>
</EditForm>

@code 
{
    SomeModel Model = new Data.SomeModel();

    void Submit()
    {
        System.Diagnostics.Debug.WriteLine("Enum " + Model.SomeEnum);
        System.Diagnostics.Debug.WriteLine("Nullable Enum " + Model.SomeNullableEnum);
        System.Diagnostics.Debug.WriteLine("Int " + Model.SomeInt);
        System.Diagnostics.Debug.WriteLine("Nullable Int " + Model.SomeNullableInt);
    }
}
Run Code Online (Sandbox Code Playgroud)

Isa*_*aac 3

不确定我理解你的意思,但是让我们尝试一下......

然而我想要一个不可为空的必需属性

例如,您的意思是否是您想要如下属性:

[Required]
public int SomeInt { get; set; }
Run Code Online (Sandbox Code Playgroud)

绑定到 InputSelect 组件,如下所示:

<InputSelect @bind-Value="Model.SomeInt">
    <option>Select Int</option>
    <option value="1">1</option>
    <option value="2">2</option>
</InputSelect>
Run Code Online (Sandbox Code Playgroud)

当用户点击“提交”按钮时,如果用户未选择值,则应显示验证消息?

如果是的话,这就是我的回答:

InputSelect组件,至少在.Net 5.0之前,只能绑定到字符串和枚举类型。

如果您想让您的 InputSelect 支持绑定到 int,如上面的情况所示,您应该按如下方式对其进行子类化...

public class InputSelectNumber<T> : InputSelect<T>
    {
        
        protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage)
        {
            if (typeof(T) == typeof(int))
            {
                if (int.TryParse(value, out var resultInt))
                {
                    result = (T)(object)resultInt;
                    validationErrorMessage = null;
                    return true;
                }
                else
                {
                    result = default;
                    validationErrorMessage = "The chosen value is not a valid number.";
                    return false;
                }
            }
            else
            {
                return base.TryParseValueFromString(value, out result, out validationErrorMessage);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

更新

我可以绑定它,但它不遵守必需的属性,不执行验证

请运行下面的代码,在名称字段中输入一个值,然后按“提交”按钮。该表格已“提交”。现在,选择一个国家/地区,然后选择“选择您的国家/地区:”...将显示一条验证消息。结论:仅当先前选择了某个值然后将其删除时才会进行验证。我不知道这是设计使然还是错误。但是,我认为此行为与 Blazor 无关。需要检查具有必需属性的 select 元素在 Razor Pages 中的行为方式。无论如何,我会尝试解决这个错误,如果成功,我会告诉你......

@using System.ComponentModel.DataAnnotations;
 
<EditForm EditContext="@EditContext" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />

    <div class="form-group">
        <label for="name">Enter your Name: </label>
        <InputText Id="name" Class="form-control" @bind-Value="@comment.Name"></InputText>
        <ValidationMessage For="@(() => comment.Name)" />

    </div>
    <div class="form-group">
        <label for="body">Select your country: </label>

        <InputSelect @bind-Value="@comment.Country" >
            <option value="0">Select country...</option>
            @foreach (var country in Enum.GetValues(typeof(Country)))
            {
            
                <option value="@country">@country</option>
            }
        </InputSelect>
               
        <ValidationMessage For="@(() => comment.Country)" />
    </div>

    <p>
        <button type="submit">Submit</button>
    </p>
</EditForm>


@code
    {
    private EditContext EditContext;
    private Comment comment = new Comment();

    private void HandleValidSubmit()
    {
        Console.WriteLine("Submitting");
    }
    protected override void OnInitialized()
    {
        EditContext = new EditContext(comment);


        base.OnInitialized();
    }

    public enum Country
    {
        USA = 1,
        Britain,
        Germany,
        Israel

    }
    public class Comment
    {
        [Required]
        public string Name { get; set; }
        [Required]
        public Country Country { get; set; }
    }

}   
Run Code Online (Sandbox Code Playgroud)