使用FluentValidation,是否可以将a验证string为可解析DateTime而无需指定Custom()委托?
理想情况下,我想说一下像EmailAddress这样的功能,例如:
RuleFor(s => s.EmailAddress).EmailAddress().WithMessage("Invalid email address");
Run Code Online (Sandbox Code Playgroud)
所以像这样:
RuleFor(s => s.DepartureDateTime).DateTime().WithMessage("Invalid date/time");
Run Code Online (Sandbox Code Playgroud) 我试图将FluentValidation 2.0与MVC 3项目一起使用.我按照这里的说明在项目中安装了FV.
这是我的验证器类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FluentValidation;
namespace HandicapTracker.Models.Validation
{
public class TournamentValidator : AbstractValidator<Tournament>
{
public TournamentValidator()
{
RuleFor(x => x.CourseId).NotEmpty();
RuleFor(x => x.TournamentDate).NotEmpty().NotEqual(new DateTime());
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试使用该属性的地方:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using HandicapTracker.Configuration;
using HandicapTracker.Models.Validation;
using Omu.ValueInjecter;
using FluentValidation;
using HandicapTracker.Models.Validation;
namespace HandicapTracker.Models
{
[Validator(typeof(TournamentValidator))]
public class Tournament : HandicapTrackerModelBase
{
private const int VisitingTeamIndex = 0;
private …Run Code Online (Sandbox Code Playgroud) 我正在尝试让客户端验证适用于使用编辑器模板的页面.
我的视图模型的简化示例是:
[Validator(typeof(ValidationTestModelValidator))]
public class ValidationTestModel
{
public string Name { get; set; }
public string Age { get; set; }
public ChildModel Child { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
儿童模型是例如:
public class ChildModel
{
public string ChildName { get; set; }
public string ChildAge { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的验证器是例如:
public class ValidationTestModelValidator : AbstractValidator<ValidationTestModel>
{
public ValidationTestModelValidator()
{
RuleFor(m => m.Name)
.NotEmpty()
.WithMessage("Please enter the name");
RuleFor(m => m.Age)
.NotEmpty()
.WithMessage("Please enter the age");
RuleFor(m => m.Age)
.Matches(@"\d*")
.WithMessage("Must …Run Code Online (Sandbox Code Playgroud) 当我们验证的对象具有也经过验证的子类时,是否可以为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) 在MVC中,ModelValidatorProvider实例化并调用a以在每个请求上验证模型.这意味着在DI环境中,它可以依赖于单个请求中作用域的对象,例如工作单元或数据库上下文.在Web API中,这似乎已经发生了重大变化.而不是按请求实例化,ModelValidatorProvider似乎是在应用程序启动期间长期存在并实例化的.然后,WebAPI缓存来自ModelValidatorProviderper类型的结果,这意味着ModelValidator不能从DI中获取任何依赖性.
我正在尝试ModelValidator使用服务定位器实现我使用工厂(请不要自动'反模式'注释!).这将允许我在每个请求中构造一个内部验证器对象,它可以从容器中获取依赖关系.但是,我无法获得一个依赖性解析器或容器作为当前请求的范围,该请求ModelValidator主要是作为Singleton的范围.我试过使用GlobalConfiguration.Configuration.DependencyResolver,但这只返回全局范围的服务(从根范围,这里也提到)
我在Autofac工作,因此特定于autofac的解决方案是合适的(例如MVC具有AutofacDependencyResolver.Current,内部使用DependencyResolver.GetService).WebAPI集成中没有可用的等价物,可能是因为上面提到的全局DependencyResolver仅返回全局范围服务的原因.
我尝试这样做(以及我自己使用)的原因是为FluentValidation实现Web API集成,目前不存在.到目前为止已经进行了两次尝试,但这些尝试都没有处理依赖注入问题,而是导致单个静态ModelValidator.
到目前为止我尝试过的事情:
GlobalConfiguration.Configuration.DependencyResolver(返回根作用域中的对象)Func<IComponentContext>(总是返回根上下文)在已删除的答案中,建议IModelValidatorProvider从Web API配置中删除服务.这必须使用反射来完成,因为接口和实现类都被定义为内部,但它确实使验证器更好地工作(因为ModelValidator是按请求构造的).但是,由于使用反射来检查模型上的验证器及其具有的每个属性,因此以这种方式执行它会有显着的性能损失,因此我不想采用此选项.
Filip W的回答建议使用HttpRequestMessage获取依赖范围,但是我没有找到任何HttpRequestMessage.Current可以在长期存在的对象中提供对该对象的访问的东西- 如果可以实现,我相信一切都会落到实处.
我正在使用FluentValidation进行服务器端验证.现在我已经让它在使用Must验证之前调用了一个函数:
RuleFor(x => x.UserProfile).Must(ValidateProfile).WithMessage("We are sorry, you have already logged on " + DateTime.Now + ". Please come again tomorrow.");
Run Code Online (Sandbox Code Playgroud)
现在,这是有效的,因为validateProfile采用的唯一参数是UserProfile.一切都很好.
我现在的问题是我正在尝试使用两个参数验证数据的函数.我尝试用于验证的函数如下所示:
bool IsValid(string promocode, IUserProfile userProfile)
Run Code Online (Sandbox Code Playgroud)
现在,我不确定如何将IsValid绑定到fluentValidation.有任何想法吗?
我使用mvc4进行流畅验证
在我的模型中,我有一个列表:
public List<int> TransDrops { get; set; }
Run Code Online (Sandbox Code Playgroud)
在视图中我为列表中的每个项目创建文本框.
我想随后确保填写每个字段.(不是空/空)
OrderDetailsViewModelValidator是模型的验证器,我需要什么?
谢谢
我有一个带有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) 我正在使用FluentValidation和登录表单.电子邮件地址字段是
必填且必须是有效的电子邮件地址.
我希望在两种情况下都显示自定义错误消息.
我工作的代码是:
RuleFor(customer => customer.email)
.NotEmpty()
.WithMessage("Email address is required.");
RuleFor(customer => customer.email)
.EmailAddress()
.WithMessage("A valid email address is required.");
Run Code Online (Sandbox Code Playgroud)
上面的代码确实有效,并显示(2)不同的错误消息.是否有更好的方法为一个字段写入多个错误消息?
更新 - 工作
每个要求工作.WithMessage 后链接和添加.
RuleFor(customer => customer.email)
.NotEmpty()
.WithMessage("Email address is required.")
.EmailAddress()
.WithMessage("A valid email address is required.");
Run Code Online (Sandbox Code Playgroud) 我有以下型号:
public class ViewDataItem
{
public string viewName { get; set; }
public UpdateIndicator updateIndicator { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用以下枚举:
public enum UpdateIndicator
{
Original,
Update,
Delete
}
Run Code Online (Sandbox Code Playgroud)
以下验证者:
public class ViewValidator : AbstractValidator<ViewDataItem>
{
public ViewValidator()
{
RuleFor(x => x.viewName).NotEmpty().WithMessage("View name must be specified");
RuleFor(x => x.updateIndicator).SetValidator(new UpdateIndicatorEnumValidator<UpdateIndicator>());
}
}
public class UpdateIndicatorEnumValidator<T> : PropertyValidator
{
public UpdateIndicatorEnumValidator() : base("Invalid update indicator") {}
protected override bool IsValid(PropertyValidatorContext context)
{
UpdateIndicator enumVal = (UpdateIndicator)Enum.Parse(typeof(UpdateIndicator), context.PropertyValue.ToString());
if (!Enum.IsDefined(typeof(UpdateIndicator), enumVal))
return …Run Code Online (Sandbox Code Playgroud) fluentvalidation ×10
c# ×6
validation ×3
.net ×2
asp.net-mvc ×1
autofac ×1
datetime ×1
enums ×1
json ×1
refactoring ×1
string ×1
unit-testing ×1