C#中ValidationError类的合理模式

时间:2010-07-29 15:52:12

标签: c# design-patterns validation enums fluentvalidation

我即将实现一个类来表示验证错误。该类肯定包含一个名为Message的字符串值,它是一个显示给用户的默认消息。我还需要一种方法来表示验证错误对程序员的影响。我们的想法是应该有一种简单的方法来确定是否发生了特定的验证错误。

实现名为Type的字符串成员会很简单,但要确定ValidationError是否属于该类型,我需要记住描述该类型的字符串。

if (validationError.Type == "PersonWithoutSurname") DoSomething();

显然,我需要一些更强类型的东西。枚举会很好:

if (validationError.Type == ValidationErrorType.PersonWithoutSurname) DoSomething();

但鉴于可能存在数百种类型的验证错误,我最终会得到一个包含数百个值的丑陋枚举。

我也想过使用子类化:

if (validationError.GetType() == typeof(PersonWithoutSurnameValidationError)) DoSomething();

但是后来我的类库中散布着数百个类,每个类大部分都会使用一次。

你们做什么?我可以花几个小时来为这种事情苦恼。

回答任何提出我使用的建议的人。 Enum建议是最好的选择。

3 个答案:

答案 0 :(得分:3)

我使用FluentValidation,您可以在其中为每个类设置规则,并为每个属性设置默认或可自定义的消息。

因为它是一个流畅的框架,您可以结合以下规则:

RuleFor(customer => customer.Address)
   .NotNull().Length(20, 250).Contains("Redmond")
   .WithMessage(@"Address is required, it must contain 
    the word Redmond and must be between 20 and 250 characters in length.");

Customer类验证器的典型用法:

public class CustomerValidator: AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Company).NotNull();
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);

bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;  
//Bind these error messages to control to give validation feedback to user; 

答案 1 :(得分:0)

我真的不明白为什么你会遇到这么多麻烦......

如果你正在进行验证字段,那么我通常会添加一个正则表达式验证器&amp;和必要的字段验证器。对于某些字段,我会为自己的规则集添加自定义验证器。但就是这样。对于客户端以及服务器端。我所做的只是一个page.validate命令,如果抛出错误就意味着客户端脚本已被修改&amp;我通常会重新加载页面作为回复。

此外,如果我想要检查单个值,我使用

 System.Text.RegularExpressions.Regex.IsMatch(...

那还有更多吗?如果有请指出。

答案 2 :(得分:-1)

如果问题是存储类型(特别是你可以添加新的类型),XML中的配置文件或数据库驱动的东西怎么样?

使用app.config可以:

将在代码中调用:

//Generate the error somehow:
Validation.ErrorType = 
    ConfigurationManager.AppSettings["PersonWithoutSurnameValidationError"].Value;

//Handle the error
[Your string solution here]

这样,您可以在代码之外的某处记录错误类型,以便更容易记住。另一方面,如果你的主要问题是存储,那么你可以得到正确的类型来处理,坚持使用枚举。