C# 对象状态变更(草稿→非草稿)时的规则验证需求
处理草稿对象的延迟验证方案
这个场景太常见了——复杂对象需要支持草稿状态(允许不完整、不符合规范的属性值),只有在用户确认要转为正式对象时才执行全量验证。普通的属性级验证(比如数据注解)确实没法直接满足,因为它往往在属性赋值时就触发,完全限制了草稿的灵活性。
我之前处理过类似需求,给你一套清晰的实现思路,分几步走:
1. 给对象添加草稿状态标记
首先给你的复杂对象加一个布尔属性来跟踪草稿状态,默认设为true:
public class ComplexObject { public bool IsDraft { get; private set; } = true; // 默认处于草稿状态 // 你的其他业务属性 public string Name { get; set; } public int? Age { get; set; } public DateTime? ExpireDate { get; set; } // ... 更多属性 }
2. 封装全量验证逻辑
单独写一个方法来处理正式状态的验证,它会检查所有需要符合规范的属性,返回详细的错误信息列表:
public List<string> ValidateForNonDraft() { var errors = new List<string>(); if (string.IsNullOrWhiteSpace(Name)) { errors.Add("名称(Name)不能为空或空白"); } if (!Age.HasValue || Age <= 0) { errors.Add("年龄(Age)必须是大于0的有效整数"); } if (!ExpireDate.HasValue || ExpireDate <= DateTime.Now) { errors.Add("过期时间(ExpireDate)必须设置为当前时间之后的日期"); } // 针对其他属性的验证逻辑... return errors; }
3. 实现StopBeingADraft()方法
在这个方法里,先触发全量验证,若存在错误就抛出异常(或者把错误列表返回给调用方),没有错误再切换状态:
public void StopBeingADraft() { var validationErrors = ValidateForNonDraft(); if (validationErrors.Any()) { // 这里可以选择抛出包含错误信息的自定义异常,或者返回错误列表 throw new InvalidOperationException("对象无法转为正式状态,存在以下问题:\n" + string.Join("\n", validationErrors)); } IsDraft = false; }
额外优化建议
- 如果属性数量特别多,可以把验证逻辑拆分到更小的方法里(比如按属性组拆分),让代码更易维护。
- 若用的是.NET生态,也可以结合
ValidationContext和Validator类复用数据注解,但需要在草稿状态下跳过自动验证,只在StopBeingADraft()时手动触发验证。 - 对于持久化场景(比如存数据库),可以在保存时检查
IsDraft状态:草稿状态直接保存,正式状态先验证再保存。
这套方案完美适配你的需求:草稿阶段允许任何属性值,只有在用户确认转为正式对象时,才执行严格的全量验证并列出所有错误。
内容的提问来源于stack exchange,提问作者ono2012
相关产品推荐
相关产品推荐

