FluentValidation在MVVM模式中的应用

在现代软件开发中,数据验证是一个不可或缺的环节。它不仅确保了数据的准确性和完整性,还提高了用户体验。FluentValidation是一个流行的.NET库,它提供了一种声明式的方式来定义验证规则。本文将介绍如何在MVVM(Model-View-ViewModel)模式中使用FluentValidation进行数据验证

FluentValidation简介

FluentValidation是一个开源的.NET库,用于构建验证规则。它支持Lambda表达式,可以避免重复代码。FluentValidation提供了多种内置验证器,如NotNullValidator、NotEmptyValidator、NotEqualValidator等。此外,它还支持自定义逻辑和错误消息。对于XAML应用程序,可以将FluentValidation与IDataErrorInfo接口结合使用,实现更强大的数据验证功能。

安装FluentValidation

要使用FluentValidation,首先需要通过NuGet下载其DLL文件。这可以通过Visual Studio的NuGet包管理器轻松完成。

定义验证规则

在MVVM模式中,验证通常在ViewModel层进行。以下是一个简单的示例,展示了如何使用FluentValidation定义验证规则:

using System; using FluentValidation; namespace FluentApplication { public class ModelValidator : AbstractValidator { public ModelValidator() { RuleFor(model => model.ID).NotEmpty(); RuleFor(model => model.ID).Must(IsNumber).WithMessage("This is not a number"); RuleFor(model => model.ID).LessThan(10).WithMessage("ID should be less than 10"); RuleFor(model => model.Name).NotEmpty(); RuleFor(model => model.Name).Length(1, 5); } private bool IsNumber(int ID) { // 自定义验证逻辑 return true; } } }

在上面的代码中,定义了一个ModelValidator类,它继承自AbstractValidator。为Model的ID和Name属性定义了一些验证规则。这些规则包括NotEmpty、LessThan和Length等内置验证器,以及一个自定义验证器IsNumber。

自定义验证逻辑

自定义验证逻辑可以通过Must方法实现。在上面的示例中,定义了一个IsNumber方法,用于验证ID属性是否为数字。这个方法的输入参数类型与调用属性的类型一致,因此IsNumber方法的输入参数将始终反映传递的属性值。

触发子验证

FluentValidation还支持子验证。例如,如果正在验证Address对象,可以进一步触发Address的内部属性,如邮政编码、街道名称等。

定义Model

MVVM模式中,Model通常是一个简单的POCO类。以下是一个简单的Model定义:

using FluentValidation.Results; using System; using System.ComponentModel; namespace FluentApplication { public class Model : IDataErrorInfo { private int _id; public int ID { get { return _id; } set { _id = value; } } private string _name; public string Name { get { return _name; } set { _name = value; } } public string Error { get; set; } public string this[string columnName] { get { var validator = new ModelValidator(); if (columnName == "Name") { if (validator.Validate(this, columnName).Errors.Any()) return validator.Validate(this, columnName).Errors.FirstOrDefault().ErrorMessage; else return string.Empty; } if (columnName == "ID") { if (validator.Validate(this, columnName).Errors.Any()) return validator.Validate(this, columnName).Errors.FirstOrDefault().ErrorMessage; else return string.Empty; } return string.Empty; } } } }

在上面的代码中,实现了IDataErrorInfo接口,这将内部触发FluentValidation。可以根据需要为单个属性或整个模型触发验证。

定义ViewModel

ViewModel是MVVM模式的核心,它负责协调Model和View之间的交互。以下是一个简单的ViewModel定义:

using System.Collections.ObjectModel; namespace FluentApplication { class ViewModel { public ViewModel() { ModelLists = new ObservableCollection(); ModelLists.Add(new Model() { ID = 1, Name = "Adi" }); ModelLists.Add(new Model() { ID = 2, Name = "Abi" }); } public ObservableCollection ModelLists { get; set; } } }

在上面的代码中,定义了一个ViewModel类,它包含一个Model列表。这个列表被绑定到View中的DataGrid控件。

定义View

View是用户界面层,负责显示数据和接收用户输入。以下是一个简单的View定义:

<Window x:Class="FluentApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <DataGrid x:Name="dgMain" ItemsSource="{Binding ModelLists,Mode=TwoWay,ValidatesOnDataErrors=True, ValidatesOnNotifyDataErrors=True, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" Margin="22,1,31,161" RenderTransformOrigin="0.5,0.5"> <DataGrid.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform AngleY="0.669"/> <RotateTransform/> <TranslateTransform Y="1.962"/> </TransformGroup> </DataGrid.RenderTransform> <DataGrid.Columns> <DataGridTextColumn Header="ID" Binding="{Binding ID,UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True}"/> <DataGridTextColumn Header="Name" Binding="{Binding Name,UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True}"/> </DataGrid.Columns> </DataGrid> </Grid> </Window>
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485