我使用流畅的验证和客户端不显眼的验证。
<fieldset class="edit-root-form">
<p>
@Html.LabelFor(model => model.Login, UserRes.Login)
@Html.TextBoxFor(model => model.Login)
@Html.ValidationMessageFor(model => model.Login)
</p>
</fieldset>
Run Code Online (Sandbox Code Playgroud)
流畅的验证规则:
this.RuleFor(x => x.Login).NotNull().EmailAddress()
Run Code Online (Sandbox Code Playgroud)
我收到了这样的错误消息:“ {PropertyName} ”不能为空。
生成的html:
<input data-val="true" data-val-regex="&#39;{PropertyName}&#39; is not a valid
email address." data-val-required="&#39;{PropertyName}&#39; must not be
empty." id="Login" name="Login" type="text" value="" class="input-validation-error">
Run Code Online (Sandbox Code Playgroud)
为什么MVC不替换PropertyName 真实字段名?
我在我的 ASP.net MVC 3 项目中使用 Fluent Validation 框架。到目前为止,我所有的验证都非常简单(确保字符串不为空,只有特定长度等),但现在我需要验证数据库中是否存在某些内容。
我试图验证的一个例子可能是:
我的页面上有一个下拉列表,其中包含所选项目的列表。我想在尝试保存新记录之前验证他们选择的项目是否确实存在于数据库中。
编辑
以下是 Fluent Validation 框架中常规验证的代码示例:
[Validator(typeof(CreateProductViewModelValidator))]
public class CreateProductViewModel
{
public string Name { get; set; }
public decimal Price { get; set; }
}
public class CreateProductViewModelValidator : AbstractValidator<CreateProductViewModel>
{
public CreateProductViewModelValidator()
{
RuleFor(m => m.Name).NotEmpty();
}
}
Run Code Online (Sandbox Code Playgroud)
控制器:
public ActionResult Create(CreateProductViewModel model)
{
if(!ModelState.IsValid)
{
return View(model);
}
var product = new Product { Name = model.Name, Price = model.Price …Run Code Online (Sandbox Code Playgroud) 我有一个MainEntity班级,它有一个SubEntity. 以下是当前的验证:
public class MainEntityValidator : AbstractValidator<MainEntity>
{
public MainEntityValidator()
{
RuleFor(x => x.SubEntities).SetCollectionValidator(new SubEntityValidator());
}
public class SubEntityValidator : AbstractValidator<SubEntity>
{
public SubEntityValidator()
{
RuleFor(x => x.Field1).NotNull();
RuleFor(x => x.Field2).NotNull();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何添加验证规则,以便只有唯一SubEntity对象(基于Field1和Field2)必须在集合中?
例如,我有一个人员验证器
public class PersonValidator : AbstractValidator<Person> {
public PersonValidator() {
RuleSet("Names", () => {
RuleFor(x => x.Surname).NotNull();
RuleFor(x => x.Forename).NotNull();
});
RuleFor(x => x.Id).NotEqual(0);
}
}
Run Code Online (Sandbox Code Playgroud)
使用 ValidateAndThrow 调用验证器时如何指定规则集
通常这是在调用 ValidateAndThrow 时所做的
public class ActionClass
{
private readonly IValidator<Person> _validator;
public ActionClass(IValidator<Person> validator)
{
_validator=validator
}
public void ValidateForExample(Person model)
{
_validator.ValidateAndThrow(model)
//When there is no error I can continue with my operations
}
}
Run Code Online (Sandbox Code Playgroud)
我知道在校准验证时可以将规则集作为参数传递
我想知道是否也可以使用ValidateAndThrow来完成?
我想用 FluentValidation 检查电子邮件格式。电子邮件不是强制性的。然后我只需要在属性不为空时检查。我该怎么做?下面我一直在检查。
RuleFor(x => x.Email)
.EmailAddress()
.WithLocalizedMessage(() => "My message.");
Run Code Online (Sandbox Code Playgroud)
谢谢
我有一个模型类:
public class MyModel() { //properties here... }
Run Code Online (Sandbox Code Playgroud)
我想验证一个MyModel对象列表。所以我创建了这个验证器:
class MyModelListValidator : AbstractValidator<List<MyModel>>
{
public MyModelListValidator ()
{
RuleFor(x => x)
.SetCollectionValidator(new MyModelValidator())
.When(x => x != null);
}
private class MyModelValidator : AbstractValidator<MyModel>
{
public MyModelValidator()
{
//MyModel property validation here...
}
}
}
Run Code Online (Sandbox Code Playgroud)
但上面的不起作用。另一种方法是创建一个类,如:
public class MyModelList()
{
public List<MyModel> Items { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这会奏效。
但是有没有办法在不使用这个额外类的情况下做到这一点?
在FluentValidation.NET之前,我可以像这样正确地给一个自定义标签:
[Display(Name="Blah")]
public string BlahBlahBlah { get; set; }
Run Code Online (Sandbox Code Playgroud)
我可以通过多种方式消耗它:
@Html.LabelFor(m => m.BlahBlahBlah)
@Html.DisplayNameFor(m => m.BlahBlahBlah)
<label asp-for="BlahBlahBlah"></label>
Run Code Online (Sandbox Code Playgroud)
现在我想从我的模型中删除所有数据注释,并转向流畅的验证。在我的验证器中,我有这个:
RuleFor(o => o.BlahBlahBlah)
.NotEmpty()
.WithName("Blah");
Run Code Online (Sandbox Code Playgroud)
但这不起作用。为什么?
我正在使用带有内置容器的 ASP.NET Core。
报名时应该做像这样:
services
.AddMvc()
.AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<Startup>())
Run Code Online (Sandbox Code Playgroud)
这会自动 1) 配置 FluentValidation,以及 2) 注册在程序集中找到的所有验证器。
但我想手动注册我的验证器。我怎么做?
我有一个 .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)
任何帮助将不胜感激。