当我们验证的对象具有也经过验证的子类时,是否可以为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) 我有一个带有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) 我在我的MVC4项目中使用FluentValidation.每件事都很完美,它与我的IoC(StructureMap)相连.
我有两个问题:
我该如何管理验证器的生命周期?可以让他们成为单身人士吗?或者没有区别,我可以根据自己的需要管理生命周期?这里的最佳做法是什么?
FluentValidation非常好.我一直在使用它进行简单的验证(例如:属性不是空的等).我正在考虑使用它做一些Db验证(比如:属性值是唯一的.)我可以使用StructureMap将我的存储库传递给它,并检查Db的值.这是个好主意吗?或者我应该在我的服务层而不是在我的IValidator中实现这个逻辑?
如果您在类似场景中使用它,您的体验是什么?
我在 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在这种情况下我需要采取额外的步骤吗?
我希望使用 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) 我昨天刚刚了解 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)
提前致谢。
我一直在使用(成功)以下验证:
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已经不被认可了。
我怎样才能解决这个问题?
我正在使用 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) 我正在使用Dictionary<string, T>数据结构将电话号码存储在视图模型中。用户可以在将它们发回服务器之前在客户端添加或删除它们。
背景故事:我正在使用字典,因为List<T>在 ASP.NET MVC 5 中使用数据结构需要表单字段的名称包含从零开始的顺序索引,并且 JavaScript 在屏幕上添加或删除这些字段变得非常痛苦无需重新排序索引值。我发现使用字典很容易。现在我正在做一个概念验证任务来启用依赖注入,这允许我们在验证期间使用我们的 NHibernate 会话来查询数据库,并使用控制器和视图模型使用的相同会话而不是 FluentValidation 的“单例”模式与 MVC 5 一起使用。
当使用[Validator(typeof(T))]视图模型上面的属性时,消息按字段显示就好了,但是验证器实例在 AppDomain 中是单例的,并且验证器使用的 NHibernate 会话与控制器使用的不同。这会导致数据在数据验证期间变得不同步。检查数据库的验证开始返回意外结果,因为 NHibernate 在服务器上缓存了如此多的数据,并且它实际上有 2 个单独的缓存。
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) 我正在使用带有 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 ×10
c# ×8
asp.net-mvc ×3
validation ×3
asp.net-core ×2
.net ×1
.net-6.0 ×1
asp.net ×1
consistency ×1
generics ×1
razor ×1
rest ×1
unit-testing ×1