能否结合FluentValidation与铁路编程模式生成验证后的非空对象?
用FluentValidation实现验证+生成非空有效对象
FluentValidation本身没有内置的“验证后直接转换为新对象”功能,但可以通过几种简洁的方式实现你要的从可空输入到非空有效对象的转换需求,完美适配C#的空状态静态分析。
方法1:验证后手动映射
先完成输入对象的验证,通过后手动构造或用映射工具生成非空的有效对象。
步骤1:编写FormData的验证器
public class FormDataValidator : AbstractValidator<FormData> { public FormDataValidator() { RuleFor(x => x.FormFile) .NotNull() .WithMessage("请上传附件"); RuleFor(x => x.CategoryId) .NotNull() .WithMessage("请选择附件类别"); // 可根据需求添加更多验证规则,比如文件大小、类型等 } }
步骤2:验证并转换
在控制器或业务逻辑中,先执行验证,通过后构造非空的FormDataValidated:
public IActionResult Upload(FormData formData) { var validator = new FormDataValidator(); var validationResult = validator.Validate(formData); if (!validationResult.IsValid) { return BadRequest(validationResult.Errors.Select(e => e.ErrorMessage)); } // 验证通过后,直接构造非空对象(!运算符告诉编译器此处已确保非空) var validatedData = new FormDataValidated { FormFile = formData.FormFile!, CategoryId = formData.CategoryId.Value }; // 后续处理validatedData return Ok("上传成功"); }
方法2:自定义验证器的转换方法
给验证器添加一个自定义方法,将“验证+转换”逻辑封装在一起,更符合函数式编程风格:
步骤1:扩展验证器并定义Result类
// 定义通用的结果类,用于返回成功/失败状态和数据 public class Result<T> { public bool IsSuccess { get; } public T? Value { get; } public IEnumerable<string> Errors { get; } private Result(bool isSuccess, T? value, IEnumerable<string> errors) { IsSuccess = isSuccess; Value = value; Errors = errors; } public static Result<T> Success(T value) => new(true, value, Enumerable.Empty<string>()); public static Result<T> Failure(IEnumerable<string> errors) => new(false, default, errors); } // 给FormDataValidator添加验证+转换方法 public class FormDataValidator : AbstractValidator<FormData> { public FormDataValidator() { RuleFor(x => x.FormFile).NotNull(); RuleFor(x => x.CategoryId).NotNull(); } public Result<FormDataValidated> ValidateAndMap(FormData input) { var validationResult = Validate(input); if (!validationResult.IsValid) { return Result<FormDataValidated>.Failure(validationResult.Errors.Select(e => e.ErrorMessage)); } return Result<FormDataValidated>.Success(new FormDataValidated { FormFile = input.FormFile!, CategoryId = input.CategoryId.Value }); } }
步骤2:使用自定义方法
var validator = new FormDataValidator(); var result = validator.ValidateAndMap(formData); if (!result.IsSuccess) { return BadRequest(result.Errors); } // 直接使用已验证的非空对象 ProcessValidAttachment(result.Value);
总结
FluentValidation的核心定位是验证规则的定义和执行,但通过上述两种方式,你可以轻松扩展出“验证+生成非空有效对象”的能力,既保留了FluentValidation的优势,又满足C#空状态分析的要求,适配函数式编程的风格。
内容的提问来源于stack exchange,提问作者boggy
相关产品推荐
相关产品推荐

