快速问一下,就功能而言,Fluent API 是否可以替代数据注释?数据注释中有哪些功能未包含在 Fluent API 中?
我想使用 Fluent API,因为关注点分离(在我的模型和持久性之间)、约定优于配置(在一个地方定义映射,DbContext.OnModelCreating()但不是在每个模型属性),并且我想使用VS 2010 层验证来确保我的 POCO 类永远不会依赖于 EF,但是如果我从源中完全删除数据注释,我会错过什么?
c# asp.net-mvc fluentvalidation data-annotations asp.net-mvc-4
我有一个名为“CustomerDataContract”的类,它具有三个属性:MobilePhone、OfficePhone 和 PrivatePhone。为了与客户取得联系,至少必须设置其中一项属性。
我创建了一个验证器类,并添加了一个名为“CheckForAnyPhoneNumber”的自定义规则,以检查是否至少提供了一个电话号码。这几乎解决了我的问题。我遇到的唯一问题是,如果我清除手机属性,它就会被评估并处于错误状态。如果我现在输入 OfficePhone 号码,则 MobilePhone 属性不会重新计算并保持错误模式。
知道如何正确解决这个问题吗?我也尝试创建规则集但没有成功。
这是(部分)CustomerDataContract:
public partial class CustomerDataContract
{
public CustomerDataContract Clone()
{
return (CustomerDataContract) MemberwiseClone();
}
public override ValidationResult SelfValidate()
{
return ValidationHelper.Validate<CustomerDataContractValidator, CustomerDataContract>(this);
}
}
Run Code Online (Sandbox Code Playgroud)
所有 DataContract 的基类:
[Serializable]
public abstract class BDataModel : IDataErrorInfo, INotifyPropertyChanged
{
[field: NonSerialized]
private ValidationResult _currentState = new ValidationResult();
public ValidationResult CurrentValidationState
{
get { return _currentState; }
set
{
_currentState = value;
OnPropertyChanged("CurrentValidationState");
OnPropertyChanged("IsValid");
OnPropertyChanged("Error");
}
}
#region INotifyPropertyChanged
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged; …Run Code Online (Sandbox Code Playgroud) 我正在使用 FluentValidation
我想使用以下方法进行范围验证:
包容性
RuleFor(x => x.Height)
.InclusiveBetween(x=> x.min, x.max).
Run Code Online (Sandbox Code Playgroud)
我希望能够从模型中动态获取“from”和“to”值......而不是在验证器中进行硬编码
这可能吗?
谢谢
通过流畅的验证,您可以在更新密码之前验证简单的内容,例如 NotNull 、 numberGreaterThan 或更高级的业务规则(例如 userMustExistsOnDb )。
我觉得当我使用流畅验证时,我执行的数据库调用次数是不使用它时的两倍。这是一个例子。
public class DeleteCustomerRequestValidator: AbstractValidator<DeleteCustomerRequest> {
public DeleteCUstomerRequestValidator() {
RuleFor(customer => customer.Id).GreaterThan(0);
RuleFor(customer => customer.Id).Must(ExistsOnDB).WithMessage("The customer does not exists");
}
private bool ExistsOnDB(int customerId) {
// DB call to check if exists on Db
return Respository.Customers.Any(x => x.Id == customerId) // CALL NUMBER 1
}
}
Run Code Online (Sandbox Code Playgroud)
这是我进行第二次调用的删除方法
public void DeleteCustomer(int customerId)
{
Customer customer = Repository.Customers.First(x => x.Id); // CALL NUMBER 2
Repository.Customers.Delete(customer)
Repository.Save()
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我不使用 Fluent 验证,我将只进行一次调用来从数据库获取客户。
public …Run Code Online (Sandbox Code Playgroud) 我正在使用 FluentValidation 来验证客户端和服务器端的模型。我使用的是最新版本:
FluentValidation.MVC5
在撰写本文时,即
5.5.0.0
我有以下简化的验证器:
public class MyViewModelValidator : AbstractValidator<MyViewModel>
{
public MyViewModelValidator()
{
RuleFor(x => x.Email)
.EmailAddress().WithLocalizedMessage(() => MyResources.Validation_Email_NotValidAddress)
.NotEmpty()
.WithLocalizedMessage(() => MyResources.Validation_Email);
}
}
Run Code Online (Sandbox Code Playgroud)
客户端似乎做了一些基本验证,例如它不会接受“@”符号两侧没有文本的任何内容,但是它会接受类似的内容test@test.
当我发布此数据时出现问题,我的控制器中有以下内容:
if (!ModelState.IsValid)
throw new Exception("Model validation error");
Run Code Online (Sandbox Code Playgroud)
由于test@test电子邮件地址,这会将模型视为无效并引发错误。所以看来我的前端验证比服务器端验证更宽松。
参考文档后,它确实声明该Email()方法受客户端支持,但是该服务器端与呈现给前端的内容之间似乎确实存在一些差异。
https://fluidation.codeplex.com/wikipage?title=mvc
如何确保客户端验证与电子邮件的服务器端验证一样彻底。
使用 FluentValidation 和Custom()规则,我希望能够验证子对象的集合,并ValidationFailure为每个无效的子对象返回 。
我无法使用集合验证器,因为子对象不包含执行规则的正确信息 - 它必须在父对象的上下文中运行。
然而,Custom()API 限制我只能返回一个ValidationFailure或根本不返回任何内容。
我可以使用一种模式来允许单个规则生成多个错误吗?
在 FluentValidation 中,有两个版本的 validate 方法:Validate 和 ValidateAsync。
我对异步版本感到困惑,为什么我们在普通验证 API 中需要它。我认为异步在 CPU 密集型操作中毫无用处,而且看起来这个验证不会涉及任何 IO 内容。
是否有任何场景我们会使用异步版本而不是同步版本?
我有课:
Sponsored { int Order };
Run Code Online (Sandbox Code Playgroud)
我收集了它:
IEnumerable<Sponsored> sponsored;
Run Code Online (Sandbox Code Playgroud)
我想检查Order这个集合是否是唯一的。
我可以通过 做吗FluentValidation?
我有:
SponsoredValidator : AbstractValidator<IEnumerable<Sponsored>>
Run Code Online (Sandbox Code Playgroud)
和
SponsoredValidator : AbstractValidator<Sponsored>
Run Code Online (Sandbox Code Playgroud)
@Edit:它应该通过 ValidationAttribute 与 WebAPI POST 方法连接
[Validator(typeof(SponsoredValidator))]
Run Code Online (Sandbox Code Playgroud) 我在让 FluentValidation 处理对象集合时遇到问题。我的控制器 POST 操作接受 IEnumerable 对象,如下所示。当我发布到一个采用单个EventInputDto且属性Url格式不正确的操作时,我的验证会成功进行。当我发布到 的集合时EventInputDto,它不起作用并且不进行验证。
如果我使用常规 MVC 属性(即必需/电子邮件),它们可以处理集合以及单个对象。我如何让它与 FluentValidation 一起使用?我不使用内部集合,所以我不确定为什么它不能按预期工作。
public async Task<IActionResult> CreateEventCollection([FromBody] IEnumerable<EventInputDto> events)
{
if (!ModelState.IsValid)
{
return UnprocessableEntity(ModelState); //does not work
}
}
Run Code Online (Sandbox Code Playgroud)
我的验证器是使用泛型设置的,因为我使用单独的模型进行输入和更新。
public class EventManipulationValidator<T> : AbstractValidator<T> where T : EventManipulationDto
{
public EventManipulationValidator()
{
RuleFor(manipulationDto => manipulationDto.Title).NotNull().WithMessage("Title cannot be blank")
.Length(1, 50);
RuleFor(manipulationDto => manipulationDto.Message).NotNull().WithMessage("Message cannot be blank")
.Length(1, 1000);
RuleFor(manipulationDto => manipulationDto.ScheduledTime).NotNull().WithMessage("Scheduled Time cannot be blank");
RuleFor(inputDto => inputDto.Url).Matches(@"https://.*windows\.net.*").WithMessage("The url must be valid …Run Code Online (Sandbox Code Playgroud) 开箱即用,当 FV 检测到验证失败时,它会以数组形式显示属性名称、错误消息、尝试值,并将其作为 BadRequest 响应返回。
然而,FV 的 validator.Validate() 方法实际上返回一个更丰富的 ValidationResult 对象,并包含有关错误代码和参数化值的元数据。
我希望能够返回实际的 ValidationResult,包括所有丰富的元数据,而不仅仅是验证失败的一些数据。
我怎样才能改变这种行为?(.net core 2.1 顺便说一句)。
fluentvalidation ×10
c# ×6
asp.net-mvc ×3
asp.net ×1
asp.net-core ×1
database ×1
validation ×1