是否有validation用户输入的最佳实践方法?

是否有validation用户输入的最佳实践方法?

实际问题:

用户在窗口中给出某些输入。 当他完成这些输入后,他可以点击“创建”。 现在,应显示一条弹出消息,其中包含所有无效输入。 如果没有无效输入,则继续。

我可以在Form类中轻松完成此操作。 但我记得在设置属性中validation输入的一些最佳实践方法。 问题是我已经创建了该类的实例(否则,无法设置属性;))如果我以这种方式validation。 这不应该发生,除非输入有效,否则不会创建类的实例。

我打算创建一个ErrorMessages类,其中包含一个列表,我可以将所有errorMessages放入其中。 每次给出无效输入时,都会在errorMessages列表中添加一条新消息。 因此,如果用户单击“创建”按钮,则会显示列表中的所有消息。 这是处理事情的好方法吗?

那么有最好的练习方式吗? 任何提供此类解决方案的设计模式?

编辑:这是一项学校任务。 所以有不合逻辑的要求。 单击“创建”时,我必须显示所有无效输入。 我想用Form类来做这个。 (因此即使没有GUI,validation也能正常工作,此时我甚至还没有创建GUI)。 首先确保我的function正常工作;)。 我想保持我的代码干净,抽象和OOP。 那么我应该如何显示我的错误消息?

我打算创建一个ErrorMessages类,其中包含一个列表,我可以将所有errorMessages放入其中。 每次给出无效输入时,都会在errorMessages列表中添加一条新消息。 因此,如果用户单击“创建”按钮,则会显示列表中的所有消息。 这是处理事情的好方法吗?

主观上,我认为提供用户输入的值无效的即时反馈会更好。 这样,他们可以立即返回并修复它。

我想说的是,考虑一下。 你提出的方法最终会给他们一个巨大的问题清单,这对用户不太友好。 此外,他们如何记住所有这些问题,以便能够一次又一次地修复它们? (提示:他们不是。)

相反,我建议使用ErrorProvider类来显示相应控件旁边的任何错误。 我在这里和这里的答案中谈了这个方法。

当然,您仍然需要确保最终提交(单击确定/提交按钮)所有输入都有效,但那只是检查是否存在任何错误的简单情况。

我可以在Form类中轻松完成此操作。 但我记得在设置属性中validation输入的一些最佳实践方法。

是的,这里的想法是封装 。 Form类应该只知道表单内容。 不应该要求知道哪种输入对所有不同的控件都有效/无效。

相反,此validation逻辑应放在其他位置,例如存储数据的类中。 该类将公开属性以获取和设置数据,并且在setter方法内部,它将validation数据。

这意味着您的表单所要做的就是在数据类上调用setter方法。 表单不需要知道如何validation数据,甚至不知道数据的含义,因为数据类处理所有这些。

这不应该发生,除非输入有效,否则不会创建类的实例。

如果确实如此,则需要为该类提供一个构造函数 ,该构造函数接受所需的所有数据作为参数。 然后,构造函数的主体将validation指定的数据,并在其中任何一个无效时抛出exception。 该exception将阻止创建类,确保不存在包含无效数据的类的实例。

这样的类可能不会在所有的getter中都有setter方法。

但是,这在C#世界中是一种不寻常的要求(不管它在C ++中是多么常见)。 通常,将validation代码放在setter中可以正常工作。

我的房产有一些私人制定者。 所以它们只能在我的数据类的构造函数中设置。 问题是,这似乎使我的validation不是eassy

为什么会改变什么呢? 您仍然处理私有设置器内部的validation。 如果validation失败,则抛出exception。 因为构造函数不处理exception,所以它继续从该方法冒泡到试图实例化该对象的代码。 如果该代码想要处理exception(例如,向用户显示错误消息),则可以这样做。

当然,在无效输入的情况下抛出exception不一定是“最佳实践”。 原因是exception通常应该保留用于意外情况,并且用户搞砸并向您提供无效数据也是可以预期的。 然而:

  1. 这是构造函数中用于数据validation的唯一选项,因为构造函数不能返回值。
  2. UI代码中的exception处理成本基本上可以忽略不计,因为现代计算机可以比用户感知屏幕上的更改更快地处理exception。

这是一个简单的要求,但有时会引起争论。 这是我的“当前”方法如何处理validation。 我还没有使用过这种方法,这只是一个概念。 需要更多地开发这种方法

首先,创建自定义validation属性

 public class ValidationAttribute : Attribute{ public type RuleType{get;set;} public string Rule{get;set;} public string[] RuleValue{get;set;} } 

其次,创建自定义error handling程序/消息

 public class ValidationResult{ public bool IsSuccess{get;set;}; public string[] ErrorMessages{get;set;}; } 

然后创建一个validation器

 public class RuleValidator{ public ValidationResult Validate(object o){ ValidationResult result = new ValidationResult(); List validationErrors = new List(); PropertyInfo[] properties = o.GetType().GetProperties(); foreach(PropertyInfo prop in properties){ // validate here // if error occur{ validationErrors.Add(string.Format("ErrorMessage at {0}", prop.Name)); //} } result.ErrorMessages = validationErrors.ToArray(); } } 

要使用它,那么你可以这样做:

 public class Person{ [ValidationAttribute(typeof(string), "Required", "true")] public string Name{get;set;} [ValidationAttribute(typeof(int), "Min", "1")] public int Age{get;set;} } 

要调用validation器

 public void ValidatePerson(Person person){ RuleValidator validator = new RuleValidator(); ValidationResult result = validator.Validate(person); // generate the error message here, use result.ErrorMessages as source } 

有什么好处:

  1. 您可以在任何应用程序平台(Winforms,Asp.Net,WCF等)中使用
  2. 您可以在属性级别设置规则
  3. 它可以进行自动validation
  4. 此方法可与DependencyInjection一起使用,并使用自定义validation器来分隔validation逻辑

缺点:

  1. 很难创建validation器
  2. 如果处理不当,validation器的数量会变得非常大
  3. 使用reflection导致性能不佳

请参阅ErrorProvider类( 此处的文档)。 它提供了一组标准的可视指示器,可以附加到大多数标准的WinForms控件上。

有几种可能的方法:

  • 使用“即时”validation。

当用户输入值时,在输入( TextChanged )期间检查并立即validation。 创建一个新类的实例,调用属性/方法应该接受string并返回bool (或者在属性的情况下抛出Exception ), false – 绘制特殊错误条件(文本框旁边的红色标签,闪烁的东西, ErrorProvider或者你可以做什么应该告诉用户“错误!”)。

我喜欢使用这个,但有点不同,通常我只检查Type ,然后只是尝试在表单中直接解析它。 如果表单与string一起操作,并且所有格式和validation都发生在类(属性设置器)中,则可以抽象更多。 或者您可以提供具有附加信息的表单(通过使用查询方法或属性),以便它可以进行即时validation,而无需实例化类或使用setter。 例如,可以在表单(或甚至控件)中识别double factor属性以执行’double.Parse, and you can have attribute DefaultValue which can be used to display to the user value in the different way when it's different from default (like it is done by值不同时which can be used to display to the user value in the different way when it's different from default (like it is done by PropertyGrid which can be used to display to the user value in the different way when it's different from default (like it is done by )。

  • 使用正常validation。

当用户完成输入时,validation(通过尝试设置值并捕获exception),如果错误 – 用户不能“离开”或“进行”直到他按ESC(取消更改)或更正输入以通过validation。

这个我不喜欢。 持有用户的想法让我烦恼(和用户ofc)。 此外,很难实现交叉检查(例如,如果你有MinMax ,那么用户将被推动以“正确”增加一个,否则失效将失败)。

  • 使用“ok”validation。

这只是意味着让用户输入所有内容并仅在他点击“确定”按钮时进行validation。

我认为组合“Ok”按钮和交互式即时validation对用户来说是最好的。 当用户通过输入知道他在哪里犯了错误,但是仍然可以自由浏览并且在点击“确定”按钮后只会从validation中获得“一巴掌”(在这一步你可以简单地向他展示他做的第一个错误,没有必要向他们展示所有)。

设置者可以使用旧式LastError方式或Exception的文本提供错误消息。