c# - 使用 InputSelect 进行 ASP.NET Blazor 所需的验证
问题描述
我试图让 Required 属性与 InputSelect 一起使用,但验证在 Blazor Server 中不起作用。无需选择即可提交表单。有趣的是,它在模型属性可以为空时起作用。在 .NET 5.0 之前,它不适用于可空类型,因为 InputSelect 不支持它们。但是,我想要一个不可为空的必需属性,因为我想将我的 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
}
这页纸
@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);
}
}
解决方案
不确定我是否理解你,但让我们试一试......
但是,我想要一个不可为空的必需属性
你的意思是,例如,你想要一个如下的属性:
[Required]
public int SomeInt { get; set; }
像这样绑定到 InputSelect 组件:
<InputSelect @bind-Value="Model.SomeInt">
<option>Select Int</option>
<option value="1">1</option>
<option value="2">2</option>
</InputSelect>
当用户点击“提交”按钮时,如果用户没有选择一个值,应该显示一条验证消息?
如果是,这是我的回答:
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);
}
}
}
更新
我可以绑定它,但它不遵守所需的属性,不执行验证
请运行下面的代码,为名称字段输入一个值,然后按“提交”按钮。表格已“提交”。现在,选择一个国家,然后选择“选择您的国家:”...显示验证消息。结论:仅当先前选择了一个值然后将其删除时,才会进行验证。这是设计的行为还是错误,我不知道。但是,我认为这种行为与 Blazor 无关。需要检查具有必需属性的选择元素在 Razor 页面中的行为方式。无论如何,我会尝试解决这个错误,如果成功,我会告诉你......
@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; }
}
}
推荐阅读
- javascript - React Native - 更新导航屏幕组件之间的状态
- angular - 箭头函数中 Angular 组件中的实例变量未定义?
- spring-boot - Spring Boot:如何从@scheduled cron 方法内部运行更新查询?
- aws-glue - AWS Glue Crawler 不同的数据类型
- testing - 有什么方法可以通过 UFT 在 SAP 屏幕上捕获消息
- ios - UITableView 不显示 UITableViewCells
- r - 使用 adonis 进行 PERMANOVA 时如何获得系数输出?
- javascript - 复选框不会从 keydown 事件更改选中的值,但仍然能够聚焦并切换到下一个元素
- c# - 在 C# 中使用空数据类型初始化列表
- typescript - Make package available in Vue with Typescript