嗨,我允许客户制作要显示的事件,这些日期有ToDate和FromDate,我需要检查ToDate是在未来还是与FromDate;相同。我使用了这个流畅的验证。
public class EventDateValidator : AbstractValidator<Event>
{
public EventDateValidator()
{
RuleFor(evd => evd.FromDate)
.NotEmpty().WithMessage("*Required");
RuleFor(evd => evd.ToDate)
.NotEmpty().WithMessage("*Required")
.GreaterThanOrEqualTo(r => r.FromDate)
.WithMessage("Date To must be after Date From");
}
}
Run Code Online (Sandbox Code Playgroud)
唯一的问题是当创建表单加载时会抛出一个空引用错误:
处理请求时发生未处理的异常。NullReferenceException:未将对象引用设置为对象的实例。FluentValidation.AspNetCore.MinLengthClientValidator.AddValidation(ClientModelValidationContext context) in MinLengthClientValidator.cs,第 22 行
GreaterThan 工作得很好,但是如果它的一天事件验证失败。
这是我第一次使用fluent,所以我的知识非常有限。我实际上是用这个问题来让我开始的。
我在我的 web api 2 项目中使用 Mediatr 4。连同 FluentValidation 和 Unity,我一直在添加一个管道行为来验证我的请求。
public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly IEnumerable<IValidator<TRequest>> _validators;
public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators)
{
_validators = validators;
}
public Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var context = new ValidationContext(request);
var failures = _validators
.Select(v => v.Validate(context))
.SelectMany(result => result.Errors)
.Where(f => f != null)
.ToList();
if (failures.Count != 0)
{
throw new ValidationException(failures);
}
return next();
}
}
Run Code Online (Sandbox Code Playgroud)
这一切都很好,但我真的希望能够在打包的响应中返回验证。我正在努力进行这样的更改,要么让它编译,要么没有 Unity 抛出运行时解决问题。 …
我想对控制器中的特定操作方法禁用模型验证。我有这个场景:
public class SomeDto
{
public string Name { get; set; }
}
public class SomeDtoValidator : AbstractValidator<SomeDto>, ISomeDtoValidator
{
public SomeDtoValidator ()
{
RuleFor(someDto=> someDto.Name).NotNull().WithMessage("Name property can't be null.");
}
}
Run Code Online (Sandbox Code Playgroud)
我有 ISomeDtoValidator 因为我以自己的方式注册了所有验证器:
public class Startup
{
// .... constructor ....
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.AddMvc(setup => {
//...others setups...
}).AddFluentValidation();
services.RegisterTypes(Configuration)
.RegisterFluentValidation()
.RegisterMappingsWithAutomapper()
.RegisterMvcConfigurations();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IConfiguration configuration)
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
我在 Controller 中有这个 Action 方法:
[DisableFormValueModelBinding]
public …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Fluent 验证来验证 Guid 列表。
我的 Id 列表应该至少有一个 Guid Id。我做了一些研究,发现类似的问题得到了回答,我最接近解决方案的是实现它,如下所示,但它仍然不起作用。当我发出请求时,即使我发送带有值的 Id 列表,它也会给我错误消息,即值不能为空。我究竟做错了什么?
public class Data
{
public List<Guid> Ids{ get; set; }
}
public class DataValidator : AbstractValidator<Data>
{
public DataValidator()
{
RuleFor(d => d.Ids).SetCollectionValidator(new GuidValidator());
}
}
public class GuidValidator : AbstractValidator<Guid>
{
public GuidValidator()
{
RuleFor(x => x).NotNull().NotEmpty();
}
}
Run Code Online (Sandbox Code Playgroud)
我也试过这个验证器,但没有用:
public class DataValidator : AbstractValidator<Data>
{
public DataValidator()
{
RuleForEach(d => d.Ids).NotNull().NotEmpty();
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个将实体保存到数据库的命令/处理程序,但在我的代码中,它首先使用 fluentvalidation 进行验证(验证管道)。
我能够创建一个成功测试来测试处理程序,但现在我想确保命令首先通过验证。
我该怎么做?我应该像处理处理程序一样独立调用验证吗?如果是这样我该怎么做
这是我的代码
[Test]
public async Task CreateCoinCommand_Success()
{
var context = new Mock<EventsContext>();
var ownersMock = CreateDbSetMock(new List<Owner>());
context.Setup(x => x.Owners).Returns(ownersMock.Object);
var handler = new CreateCoinCommandHandler(context.Object, mapper.Object );
var cmd = new CreateCoinCommand(1, "sym", "name", null, null, null, 1, "description",
null, "https://google.com", null, null, null, new []{1,2});
var cltToken = new System.Threading.CancellationToken();
var result = await handler.Handle(cmd, cltToken);
Assert.IsInstanceOf<Unit>(result);
}
Run Code Online (Sandbox Code Playgroud)
我的验证器被称为 CreateCoinCommandValidator
我有一个 .NET Core Web Api 应用程序,它按以下方式排列 -
说了这么多,这里只是一个例子。如果我想在系统中创建一个用户,我在“UsersController”中有一个名为“PostUser”的路由/方法。“UsersController”注入“UserService”。“UserService”有一个名为“CreateUser”的方法。所以在控制器的“PostUser”方法内部,它看起来像这样 -
var user = _userService.CreateUser(user);
Run Code Online (Sandbox Code Playgroud)
现在在“CreateUser”方法中它看起来像这样 -
UserValidation validation = new UserValidation(UnitOfWork, DatabaseOperation.Create);
ValidationResult validationResult = await validation.ValidateAsync(user);
Run Code Online (Sandbox Code Playgroud)
因此,UnitOfWork 通过依赖注入传递到 UserService,然后传递给 FluentValidation 类“UserValidation”,以便验证类可以执行数据库检查。我还将枚举传递给 UserValidation 类,以指定验证是用于更新还是创建。
我试图验证的 User 对象将具有诸如“Role”和“Company”之类的属性,并且我还为每个对象(RoleValidation 和 CompanyValidation)提供了单独的验证类。这两个验证类还将传入一个 UnitOfWork 以及这是创建还是更新。
这是我的 UserValidation 类的示例 -
public class UserValidation : AbstractValidator<UserDTO>
{
private IUnitOfWork _unitOfWork;
public UserValidation(IUnitOfWork unitOfWork, DatabaseOperation databaseOperation)
{
_unitOfWork = unitOfWork;
if (databaseOperation == DatabaseOperation.Create)
{
// Do Create specific validation
} …Run Code Online (Sandbox Code Playgroud) 我最近发现了 FluentValidator 并开始玩依赖注入。我似乎无法弄清楚如何使用当前的 DI 设置将值传递给子验证器。
我想从 InvoiceDetailsValidator 访问 Invoice.InvoiceNumber。
public class InvoiceValidator : AbstractValidator<Invoice>
{
private readonly IDbContextFactory<DbContext> dbContextFactory;
public InvoiceValidator(InvoiceDetailsValidator invoiceDetailsValidator, IDbContextFactory<DbContext> dbContextFactory)
{
...
RuleFor(x => x.InvoiceNumber)
.Must(BeSomething)
.WithMessage("Invoice number is required.");
RuleForEach(x => x.InvoiceDetails)
.SetValidator(invoiceDetailsValidator);
}
}
Run Code Online (Sandbox Code Playgroud)
public class InvoiceDetailsValidator : AbstractValidator<InvoiceDetails>
{
public InvoiceDetailsValidator(IDbContextFactory<DbContext> dbContextFactory)
{
...
RuleFor(x => x.InvoiceSection)
.NotEmpty()
.When(X => !string.IsNullOrEmpty( /* InvoiceNumber? */ ))
.WithMessage("Invoice section is required.");
}
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激。
我已经开始FluentValidation在 WPF 项目中使用它,直到现在我以一种简单的方式使用它来检查字段是否已填充或少于 n 个字符。
现在我必须检查插入的值(这是一个字符串......该死的旧代码)是否大于 0。有没有一种简单的方法可以使用
RuleFor(x=>x.MyStringField).Somehow().GreaterThen(0) ?
Run Code Online (Sandbox Code Playgroud)
提前致谢
我们在 .Net Core WPF 应用程序中使用 ReactiveUI.WPF 11.0.1。我们正在考虑用基于 ReactiveUI 的绑定替换所有基于 XAML 的绑定。有一个用于实现 INotifyPropertyChanged 和 INotifyDataErrorInfo 的域类型的 ViewModel:
public class ItemViewModel : INotifyPropertyChanged, INotifyDataErrorInfo
{
private string Error => string.IsNullOrEmpty(Name) ? "Empty name" : string.Empty;
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged();
}
}
public IEnumerable GetErrors(string propertyName)
{
if (string.IsNullOrEmpty(Error))
return Enumerable.Empty<string>();
return new[] {Error};
}
public bool HasErrors => !string.IsNullOrEmpty(Error);
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] …Run Code Online (Sandbox Code Playgroud) 我正在努力为一个类实现一个验证器,其中应该只设置一个属性。
假设我们有以下类:
public class SomeClass
{
public DateTime SomeDate {get; set;}
public IEnumerable<int> FirstOptionalProperty {get; set;}
public IEnumerable<int> SecondOptionalProperty {get; set;}
public IEnumerable<int> ThirdOptionalProperty {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
这个类有一个强制性属性 - SomeDate。其他属性是可选的,只能设置一个,例如如果FirstOptionalProperty设置了 -SecondOptionalProperty并且ThirdOptionalProperty应该为空,如果SecondOptionalProperty设置了 -FirstOptionalProperty并且ThirdOptionalProperty应该为空等等。
换句话说:如果设置了 IEnumerable 道具之一 - 其他 IEnumerables 应该为空。
关于为此类类实现验证器的任何提示/想法?我唯一想到的是编写When规则块,但是这种编写代码的方式很容易出错,而且结果看起来很丑陋。
fluentvalidation ×10
c# ×8
.net-core ×3
asp.net-core ×2
mediatr ×2
reactiveui ×1
validation ×1
wpf ×1