练习 - 将服务器端和客户端数据验证添加到地址表单
Blazor 可以将表单绑定到应用程序中的模型。 如果用数据注释来修饰这些模型,则可以在不编写更多代码的情况下进行客户端验证和服务器端验证。
如果客户端未输入姓名和一些地址字段,则该应用不能正确下单。 团队希望你增强验证以添加更多字段。 他们还希望具有一些最小长度和字符验证。
在本练习中,你将替换当前的服务器端验证,以使用数据注释。 你将了解如何管理验证消息并改进现成的验证支持。 在最后一步中,将控制表单的提交方式,只有在所有字段均有效时才能提交表单。
向 Blazor 模型添加数据注释
在 Visual Studio Code 的文件资源管理器中,展开“模型”,然后选择“Address.cs”。
在类的顶部添加对
System.ComponentModel.DataAnnotations
的引用。using System.ComponentModel.DataAnnotations;
对于每个必填字段,请添加数据注释。
public class Address { public int Id { get; set; } [Required, MinLength(3), MaxLength(100)] public string Name { get; set; } [Required, MinLength(5), MaxLength(100)] public string Line1 { get; set; } [MaxLength(100)] public string Line2 { get; set; } [Required, MinLength(3), MaxLength(50)] public string City { get; set; } [Required, MinLength(3), MaxLength(20)] public string Region { get; set; } [Required, RegularExpression(@"^([0-9]{5})$")] public string PostalCode { get; set; } }
在文件资源管理器中,展开“页面”,然后选择“Checkout.razor”。
在结尾
</EditForm>
标记的上方,添加验证摘要和数据注释验证程序。<ValidationSummary /> <DataAnnotationsValidator /> </EditForm> </div>
在 EditForm 标记中,替换
OnSubmit
参数以使用有效提交。<EditForm Model=Order.DeliveryAddress OnValidSubmit=PlaceOrder>
现在可以删除自定义服务器端逻辑,以测试该地址是否有效。 删除
@code
块中的CheckSubmission
方法。
测试新的数据注释验证
在 Visual Studio Code 中,按 F5 或选择“运行”>“开始调试”。
尝试在不输入任何信息的情况下订购一些比萨,然后尝试输入不完整的信息。 查看每个字段的详细错误消息。
此交互改进了每个字段的错误检查,但是每个字段的出错情况要比旁边的相关字段好得多。
按 Shift + F5 停止正在运行的应用。
改进 EditFrom 错误消息
在文件资源管理器中,展开“页面”,然后选择“Checkout.razor”。
删除 Blazor
<ValidationSummary />
组件。<DataAnnotationsValidator /> </EditForm> </div>
在文件资源管理器中,展开“共享”,然后选择“AddressEditor.razor”。
在每个字段下方添加自定义验证消息。
<div class="form-field"> <label>Name:</label> <div> <InputText @bind-Value="Address.Name" /> <ValidationMessage For="@(() => Address.Name)" /> </div> </div> <div class="form-field"> <label>Line 1:</label> <div> <InputText @bind-Value="Address.Line1" /> <ValidationMessage For="@(() => Address.Line1)" /> </div> </div> <div class="form-field"> <label>Line 2:</label> <div> <InputText @bind-Value="Address.Line2" /> <ValidationMessage For="@(() => Address.Line2)" /> </div> </div> <div class="form-field"> <label>City:</label> <div> <InputText @bind-Value="Address.City" /> <ValidationMessage For="@(() => Address.City)" /> </div> </div> <div class="form-field"> <label>Region:</label> <div> <InputText @bind-Value="Address.Region" /> <ValidationMessage For="@(() => Address.Region)" /> </div> </div> <div class="form-field"> <label>Postal code:</label> <div> <InputText @bind-Value="Address.PostalCode" /> <ValidationMessage For="@(() => Address.PostalCode)" /> </div> </div>
在文件资源管理器中,展开“模型”,然后选择“Address.cs”。
为每个字段的数据注释添加自定义错误消息。
public class Address { public int Id { get; set; } [Required, MinLength(3, ErrorMessage = "Please use a Name bigger than 3 letters."), MaxLength(100, ErrorMessage = "Please use a Name less than 100 letters.")] public string Name { get; set; } [Required, MinLength(5, ErrorMessage = "Please use an Address bigger than 5 letters."), MaxLength(100, ErrorMessage = "Please use an Address less than 100 letters.")] public string Line1 { get; set; } [MaxLength(100)] public string Line2 { get; set; } [Required, MinLength(3, ErrorMessage = "Please use a City bigger than 3 letters."), MaxLength(50, ErrorMessage = "Please use a City less than 50 letters.")] public string City { get; set; } [Required, MinLength(3, ErrorMessage = "Please use a Region bigger than 3 letters."), MaxLength(20, ErrorMessage = "Please use a Region less than 20 letters.")] public string Region { get; set; } [Required, RegularExpression(@"^([0-9]{5})$", ErrorMessage = "Please use a valid Postal Code with five numbers.")] public string PostalCode { get; set; } }
测试新的数据注释验证
在 Visual Studio Code 中,按 F5 或选择“运行”>“开始调试”。
地址表单会在包含无效数据的字段下方动态显示错误消息。 此交互发生在客户端,可防止客户输入错误地址。
按 Shift + F5 停止正在运行的应用。
还原整个错误信息并禁用“提交”按钮
在文件资源管理器中,展开“页面”,然后选择“Checkout.razor”。
添加将调用
EditForm
组件的ShowError
方法的OnInvalidSubmit
参数。<EditForm Model=Order.DeliveryAddress OnValidSubmit=PlaceOrder OnInvalidSubmit=ShowError>
添加更新
isError
属性的 ShowError 方法。protected void ShowError() { isError = true; }
更改
PlaceOrder
方法以更新isError
和isSubmitting
属性。async Task PlaceOrder() { isError = false; isSubmitting = true; var response = await HttpClient.PostAsJsonAsync( $"{NavigationManager.BaseUri}orders", OrderState.Order); var newOrderId= await response.Content.ReadFromJsonAsync<int>(); OrderState.ResetOrder(); NavigationManager.NavigateTo($"myorders/{newOrderId}"); }
在 Visual Studio Code 中,按 F5 或选择“运行”>“开始调试”。
如果客户尝试提交无效表单,将显示错误消息。
按 Shift + F5 停止正在运行的应用。
当所有字段都正确时,启用“提交”按钮
客户在完成所有字段之前无法提交订单是否会提供更好的用户体验? 让我们更改结帐页面以满足此要求。 更改 EditForm
以使用 EditContext(而不是模型)。
在文件资源管理器中,展开“页面”,然后选择“Checkout.razor”。
更新
EditFrom
元素。<EditForm EditContext=editContext OnValidSubmit=PlaceOrder>
更改按钮元素以使用
isError
参数。<button class="checkout-button btn btn-warning" type="Submit" disabled=@isError>
在
@code
块中,为新的EditContext
添加一个声明。private EditContext editContext;
使用订单派送地址初始化上下文。
protected override void OnInitialized() { editContext = new(Order.DeliveryAddress); editContext.OnFieldChanged += HandleFieldChanged; }
此代码还允许在更改字段时链接事件处理程序。 在新的处理程序中,可以检查模型是否有效以及是否相应地设置
isError
。private void HandleFieldChanged(object sender, FieldChangedEventArgs e) { isError = !editContext.Validate(); StateHasChanged(); }
由于现在已经创建了一个事件处理程序,因此我们应在结帐组件不再需要它时将其释放。
public void Dispose() { editContext.OnFieldChanged -= HandleFieldChanged; }
若要实现
Dispose
此功能,还必须让 Blazor 知道。 在页面顶部的@inject
语句下方添加此代码。@implements IDisposable
删除对
isSubmitting
的所有引用并更新PlaceOrder
方法。async Task PlaceOrder() { var response = await HttpClient.PostAsJsonAsync(NavigationManager.BaseUri + "orders", OrderState.Order); var newOrderId= await response.Content.ReadFromJsonAsync<int>(); OrderState.ResetOrder(); NavigationManager.NavigateTo($"myorders/{newOrderId}"); }
在 Visual Studio Code 中,按 F5 或选择“运行”>“开始调试”。
此时系统会提示客户输入信息,并开始禁用“下单”按钮。 只有在所有必填字段都包含数据后,按钮才会变得可点击。
按 Shift + F5 停止正在运行的应用。