C# 中 ValidationError 类的合理模式

发布于 2024-09-12 04:38:42 字数 719 浏览 6 评论 0原文

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

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

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

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

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

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

我也想到使用子类化:

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

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

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

回答任何提出我使用的建议的人。枚举建议是最值得击败的。

I am about to implement a class to represent a validation error. The class would definitely contain a string value called Message, which is a default message to display to a user. I also need a way to represent what the validation error is to the programmer. The idea is that there should be an easy way to determine if a particular validation error occurred.

It would be simple to implement a string member called Type, but to determine if a ValidationError is of that type, I would need to remember the string that describes that type.

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

Clearly, I need something more strongly typed. An enumeration would be good:

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

But given the potentially hundreds of types of validation error, I could end up with an ugly enum with hundreds of values.

It also occurred to me to use subclassing:

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

But then my class library is littered with hundreds of classes which will mostly be used once each.

What do you guys do? I can spend hours agonising over this sort of thing.

Answer go to whoever comes up with the suggestion I use. Enum suggestion is the one to beat.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

过去的过去 2024-09-19 04:38:42

我使用 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; 

I use FluentValidation, where you can set up rules for each class, with default or customisable messages for each property.

Because it is a fluent framework, you can combine rules such as:

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.");

Typical usage for a validator of the Customer class:

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; 
软的没边 2024-09-19 04:38:42

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

如果它验证你正在做的字段,那么我通常会添加一个正则表达式验证器和一个正则表达式验证器。和一个必需的字段验证器。对于某些字段,我确实为我自己的规则集添加了自定义验证器。但仅此而已。对于客户端和服务器端。然后我所做的就是一个 page.validate 命令,如果抛出错误,则意味着客户端脚本已被修改&我通常重新加载页面作为响应。

另外,如果我想处理对单个值的检查,我会使用

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

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

I seriously don't get why you getting into so much trouble....

If its validating fields that you are doing, then I usually add a regex validator & and a required field validator. For some fields I do add custom validator for my own set of rules. But that's it. For the client side as well as server side. All I do then is a page.validate command which if ever throws an error means the client script has been modified & I usually reload the page as response.

Also if I want to handle a check to single value I use

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

So Is there more to this?? If there is please point out.

黑色毁心梦 2024-09-19 04:38:42

如果问题是存储类型(尤其是这样您可以添加新类型),那么 XML 中的配置文件或数据库驱动的文件怎么样?

通过 app.config 你可以:

这将在代码中调用:

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

//Handle the error
[Your string solution here]

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

If the question is storing the types (especially so you can add new ones) how about a config file in XML, or something database driven?

With an app.config you could have:

Which would get called in code:

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

//Handle the error
[Your string solution here]

This way, you get your error types documented somewhere outside your code so they're easier to remember. If, on the other hand, your main question is the storage so you can get the correct type to handle, stick with the enum.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文