标签: fluentvalidation

单元测试具有子/子类的类的FluentValidation规则

当我们验证的对象具有也经过验证的子类时,是否可以为fluentvalidation类编写单元测试.

举个例子:我的班级看起来像这样

public class TestModel
{

    public class SubData
    {
        public int SubDataVal { get; set; }
    }

    public int ParentVal { get; set; }
    public SubData Sub { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

我的验证逻辑如下所示:

public class TestModelValidator : AbstractValidator<TestModel>
{
    public TestModelValidator()
    {
        RuleFor(o => o.ParentVal).GreaterThan(0);
        RuleFor(o => o.Sub.SubDataVal).GreaterThan(0);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我写下面的单元测试时

    [Test]
    public void Should_have_error_when_val_is_zero()
    {
        validator = new TestModelValidator();
        validator.ShouldHaveValidationErrorFor(model => model.ParentVal, 0);
    }
Run Code Online (Sandbox Code Playgroud)

我得到一个"System.NullReferenceException:对象引用未设置为对象的实例." 来自FluentValidation.TestHelper.ValidatorTester`2.ValidateError(T instanceToValidate)的异常

(如果我删除RuleFor(o => o.Sub.SubDataVal).GreaterThan(0);行,那么它可以工作!)

同样,如果我尝试用以下单元测试实际的子类:

    [Test]
    public void …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing fluentvalidation

8
推荐指数
2
解决办法
7184
查看次数

(最佳实践)FluentValidation和检查重复实体

我有一个带有3个主键的表(联结表),因此当我想检查重复记录时,我必须一起检查3个属性

我写了一个像这样的方法

    private bool IsDuplicate(long roleId, long componentGroupId, long operationId)
    {
        var business = new RoleGroupBusiness();
        var result = business.Where(x => x.RoleID == roleId && x.ComponentGroupID == componentGroupId && x.OperationID == operationId).Any();
        return result;
    }
Run Code Online (Sandbox Code Playgroud)

我有一个像这样的FluentValidator类:

public class RoleGroupValidator : AbstractValidator<RoleGroup>
{

    private bool IsDuplicate(long roleId, long componentGroupId, long operationId)
    {
        var business = new RoleGroupBusiness();
        var result = business.Where(x => x.RoleID == roleId && x.ComponentGroupID == componentGroupId && x.OperationID == operationId).Any();
        return result;
    }
    public RoleGroupValidator()
    {
        RuleFor(x => …
Run Code Online (Sandbox Code Playgroud)

c# validation fluentvalidation

8
推荐指数
2
解决办法
3701
查看次数

FluentValidation,Validators生命周期以及使用Validators检查Db

我在我的MVC4项目中使用FluentValidation.每件事都很完美,它与我的IoC(StructureMap)相连.

我有两个问题:

  1. 我该如何管理验证器的生命周期?可以让他们成为单身人士吗?或者没有区别,我可以根据自己的需要管理生命周期?这里的最佳做法是什么?

  2. FluentValidation非常好.我一直在使用它进行简单的验证(例如:属性不是空的等).我正在考虑使用它做一些Db验证(比如:属性值是唯一的.)我可以使用StructureMap将我的存储库传递给它,并检查Db的值.这是个好主意吗?或者我应该在我的服务层而不是在我的IValidator中实现这个逻辑?

如果您在类似场景中使用它,您的体验是什么?

.net c# asp.net asp.net-mvc fluentvalidation

7
推荐指数
1
解决办法
3061
查看次数

FluentValidation ShouldHaveValidationErrorFor 与 SetCollectionValidator

我在 ASP.NET MVC 项目中使用 FluentValidation 库,从 UI 角度来看,它按预期工作。违反规则会显示正确的错误。

我有一个父类,它有一个验证器和一个集合属性,其中该类型有一个验证器。它在概念上与文档中描述的相同。

我有一个父类的验证器......

public class MyFormValidator : AbstractValidator<MyFormViewModel>
Run Code Online (Sandbox Code Playgroud)

...我有一个收藏MyFormViewModel...

public IList<ChildRow> ChildRowsAdded { get; set; }
Run Code Online (Sandbox Code Playgroud)

...我为该子类的集合创建一个验证器...

public class ChildRowValidator : AbstractValidator<ChildRow>
Run Code Online (Sandbox Code Playgroud)

...并且我在父验证器中使用该子验证器...

RuleFor(m => m.ChildRowsAdded).SetCollectionValidator(new ChildRowValidator());
Run Code Online (Sandbox Code Playgroud)

在编写一些单元测试时,我注意到这ShouldHaveValidationErrorFor并不能确认错误的存在。

_validator.ShouldHaveValidationErrorFor(x => x.ChildRowsAdded, model);
Run Code Online (Sandbox Code Playgroud)

我的测试中的那一行似乎没有看到错误。测试失败并显示消息

FluentValidation.TestHelper.ValidationTestException:预计属性 AllergyRowsAdded 出现验证错误。

如果我手动.Validate()查看结果,我会看到错误。

以前有人遇到过这个吗?ShouldHaveValidationErrorFor在这种情况下我需要采取额外的步骤吗?

asp.net-mvc fluentvalidation

7
推荐指数
2
解决办法
8337
查看次数

Dto 和 Domain 模型的一致验证规则

我希望使用 FluentValidation 验证我的 Dto 和域模型。我已经定义了一个 Validator 类来验证我的 Dto,如下所示。

但是,如果我还想为我的域模型添加一个验证器,则其中一个验证器的更改不会反映在另一个中。就像,如果我将密码长度的规则从 6 更改为 7,我将不得不在两个地方更改它。

是否有某种方法可以潜在地从域模型或类似的东西继承规则,以在 Dto 和域模型之间实现一致的规则?

到:

public class NewUserDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Username { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
}

public class NewUserDtoValidator : AbstractValidator<NewUserDto>
{
    public NewUserDtoValidator()
    {
        RuleFor(x => x.FirstName).Length(2, 50);
        RuleFor(x => x.LastName).Length(2, 50);
        RuleFor(x => x.Email).EmailAddress();
        RuleFor(x => x.Username).Length(4, 25); …
Run Code Online (Sandbox Code Playgroud)

c# validation consistency fluentvalidation

7
推荐指数
1
解决办法
1283
查看次数

使用 Fluent 验证的 Model T 通用验证器?

我昨天刚刚了解 Fluent Validation,我认为它非常酷。我已经尝试过并且有效。但我的应用程序目前有多个模型,我必须承认为每个模型编写验证器很有压力。是否有可能用泛型编写它并找到一种方法来验证每个模型?

这就是我的验证器目前的编写方式。但我不知道如何用泛型编写它。

EmployeeValidator.cs

public class EmployeeValidator : AbstractValidator<EmployeeViewModel>
{
    private readonly ValidationEntitySettingServices _validationEntitySettingService;

    public EmployeeValidator(ValidationEntitySettingServices validationEntitySettingService)
    {
        _validationEntitySettingService = validationEntitySettingService;

        RuleFor(x => x.LastName).NotEmpty().When(x => IsPropertyRequired(x.LastName)).WithMessage("Last Name is a required field!");
        RuleFor(x => x.FirstName).NotEmpty().When(x => IsPropertyRequired(x.FirstName)).WithMessage("First Name is a required field!");
        RuleFor(x => x.MiddleName).NotEmpty().When(x => IsPropertyRequired(x.MiddleName)).WithMessage("Middle Name is a required field!");
    }

    public bool IsPropertyRequired(string propertyName)
    {
        var empValidationSetting = _validationEntitySettingService.GetIncluding("Employee");
        if (empValidationSetting != null)
        {
            return empValidationSetting.ValidationEntityProperties.Any(p => p.PropertyName.Equals(propertyName) && p.IsRequired);
        }
        else
            return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

提前致谢。

c# generics fluentvalidation

7
推荐指数
1
解决办法
1万
查看次数

如何使用 RuleForEach 验证集合项

我一直在使用(成功)以下验证:

RuleFor(x => x.Items)
  .SetCollectionValidator(new ItemValidator())
  .Must(coll => coll.Sum(item => item.Percentage) == 100)
  .When(x => x.Items != null);
Run Code Online (Sandbox Code Playgroud)

由于上述SetCollectionValidator内容(将)被弃用,我将其更改为:

RuleForEach(x => x.Items)
  .SetValidator(new ItemValidator())
  .Must(coll => coll.Sum(item => item.Percentage) == 100)
  .When(x => x.Items != null);
Run Code Online (Sandbox Code Playgroud)

然而,Sum已经不被认可了。

我怎样才能解决这个问题?

c# fluentvalidation

7
推荐指数
1
解决办法
1919
查看次数

ModelState无效时触发InvalidModelStateResponseFactory

我正在使用 asp.net core 3.0 编写一个 API,并为所有控制器配置了以下行为的应用程序:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
        .ConfigureApiBehaviorOptions(setupAction =>
        {
            setupAction.InvalidModelStateResponseFactory = context =>
            {
                var problemDetails = new ValidationProblemDetails(context.ModelState)
                {
                    Type = "https://courselibrary.com/modelvalidationproblem",
                    Title = "One or more model validation errors occurred.",
                    Status = StatusCodes.Status422UnprocessableEntity,
                    Detail = "See the errors property for details",
                    Instance = context.HttpContext.Request.Path
                };

                problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                return new UnprocessableEntityObjectResult(problemDetails)
                {
                    ContentTypes = { "application/problem+json" }
                };
            };
        });
    ...
}
Run Code Online (Sandbox Code Playgroud)

[Required]这对于我的输入(例如:)类属性上的数据注释非常有效。如果任何注释失败,它会返回 422 Unprocessable Entity 响应,如下所示:

{
    "type": "https://courselibrary.com/modelvalidationproblem",
    "title": "One …
Run Code Online (Sandbox Code Playgroud)

c# rest fluentvalidation asp.net-core

7
推荐指数
1
解决办法
9308
查看次数

如何使用 FluentValidation 验证 Dictionary&lt;string, T&gt; 视图模型属性中的项目

我正在使用Dictionary<string, T>数据结构将电话号码存储在视图模型中。用户可以在将它们发回服务器之前在客户端添加或删除它们。


背景故事:我正在使用字典,因为List<T>在 ASP.NET MVC 5 中使用数据结构需要表单字段的名称包含从零开始的顺序索引,并且 JavaScript 在屏幕上添加或删除这些字段变得非常痛苦无需重新排序索引值。我发现使用字典很容易。现在我正在做一个概念验证任务来启用依赖注入,这允许我们在验证期间使用我们的 NHibernate 会话来查询数据库,并使用控制器和视图模型使用的相同会话而不是 FluentValidation 的“单例”模式与 MVC 5 一起使用。

当使用[Validator(typeof(T))]视图模型上面的属性时,消息按字段显示就好了,但是验证器实例在 AppDomain 中是单例的,并且验证器使用的 NHibernate 会话与控制器使用的不同。这会导致数据在数据验证期间变得不同步。检查数据库的验证开始返回意外结果,因为 NHibernate 在服务器上缓存了如此多的数据,并且它实际上有 2 个单独的缓存。


项目设置

  • ASP.NET MVC 5
  • .NET Framework 4.5.1(但我们可以升级)
  • FluentValidation v8.5.0
  • FluentValidation.Mvc5 v8.5.0
  • FluentValidation.ValidatorAttribute v8.5.0

查看模型

public class PersonForm
{
    public PhoneFieldsCollection Phones { get; set; }
}

public class PhoneFieldsCollection
{
    public Dictionary<string, PhoneNumberFields> Items { get; set; }
}

public class PhoneNumberFields
{
    [Display(Name="Country Code")]
    [DataType(DataType.PhoneNumber)]
    public string …
Run Code Online (Sandbox Code Playgroud)

c# validation asp.net-mvc fluentvalidation

7
推荐指数
0
解决办法
2232
查看次数

即使未定义表单字段也是必需的

我正在使用带有 Fluent Validation 的 Net 6,并且我有一个包含以下字段的表单:

  <form method="post" asp-controller="Product" asp-action="Create" asp-antiforgery="true" autocomplete="off">
    <label asp-for="Description">Description</label>
    <input asp-for="Description" type="text"> 
    <span asp-validation-for="Description" class="error"></span>
    ...
    <button class="submit" name="button">Create</button>   
  </form>
Run Code Online (Sandbox Code Playgroud)

ProductModel

public class ProductModel {

  public String Description { get; set; }

  // ...
}
Run Code Online (Sandbox Code Playgroud)

ProductModel Fluent 验证器是:

公共类模型验证器:AbstractValidator {

public ModelValidator() {

  RuleFor(x => x.Description)
    .Length(0, 200).WithMessage("Do not exceed 200 characters");

  // ...

} 
Run Code Online (Sandbox Code Playgroud)

}

当我提交表单时,如果将其留空,则会出现描述错误:

The Description field is required.
Run Code Online (Sandbox Code Playgroud)

但我的验证器不需要描述。

这发生在所有领域。当未填写时,我会收到类似的错误。

我缺少什么?

fluentvalidation razor asp.net-core .net-6.0

7
推荐指数
1
解决办法
6277
查看次数