验证:流利验证与反思-最佳做法/效果

问题描述 投票:1回答:0

我有一个清单应用程序,该应用程序使用安装在计算机上的代理来读取一些信息,并将其传递给服务器以进行进一步处理。 同样,它将存储在数据库中。

现在,我想知道该信息的有效性(例如计算机的名称,操作系统,已安装的软件等)。

我确实想在代理端对数据进行预验证,以避免将数据发送到服务器,这可能会损害数据库或以后的处理类并导致错误。 当然,我还将在服务器端验证数据,以防止任何人将有害代码发送到服务器。 因此,我不需要对代理进行超级精确的验证。

另外,要了解验证错误,无论如何都必须以某种方式将数据发送到服务器,但是我想确保自己了解这一点,因此可以首先对它进行不同的处理。 我的计划是将其发送到服务器,服务器将其存储在日志文件中以进行进一步分析。

我偶然发现了反射,发现可以在标记的答案中使用一小段代码来针对正则表达式验证所有整数,字符串等:

使用FluentValidation库自动进行属性验证过程

public class Validator<T> : AbstractValidator<T>
{
public Validator(Func<PropertyInfo, bool> filter) {
    foreach (var propertyInfo in typeof(T)
        .GetProperties()
        .Where(filter)) {
        var expression = CreateExpression(propertyInfo);
        RuleFor(expression).NotEmpty();
    }
}

private Expression<Func<T, object>> CreateExpression(PropertyInfo propertyInfo) {
    var parameter = Expression.Parameter(typeof(T), "x");
    var property = Expression.Property(parameter, propertyInfo);
    var conversion = Expression.Convert(property, typeof(object));
    var lambda = Expression.Lambda<Func<T, object>>(conversion, parameter);

    return lambda;
}
}

And it can be used as such:

private static void ConfigAndTestFluent()
{
    CustomerDto customer = new CustomerDto();
    Validator<CustomerDto> validator = new Validator<CustomerDto>(x=>x.Name!="Remarks"); //we specify here the matching filter for properties
    ValidationResult results = validator.Validate(customer);
}

我会用它与字符串/整数等的区别来完成。 但是我读到反射太慢了,应该尽可能避免。

遵循JeremySkinner的FluentValidation手册,我将做一些他在这里显示的操作:

https://github.com/JeremySkinner/FluentValidation/wiki

using FluentValidation;

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

然后遍历每个错误,重新检查属性类型和用于将其发送回服务器的规则。 缺点是我必须为每个属性都做一个验证规则,我认为这是最佳实践,但是也需要更多工作。

我没有找到任何明确的答案,或者也许我只是不理解,所以我想请教一些意见并提供帮助。 速度实际上不是问题,但我想知道自己在做什么以及这样做可能会牺牲什么。

因此,我的问题是:

  • 在我的情况下,验证的最佳做法是什么?
  • 我应该走一条长路要单独验证每个属性吗?
  • 还有其他方法可以达到更好的效果吗?

任何帮助是极大的赞赏。

谢谢 :)

c# performance validation reflection fluentvalidation
© www.soinside.com 2019 - 2024. All rights reserved.