我需要能够提供IComponentContext给我ValidatorFactory解决FluentValidation Validators.我有点卡住了.
ValidatorFactory
public class ValidatorFactory : ValidatorFactoryBase
{
private readonly IComponentContext context;
public ValidatorFactory(IComponentContext context)
{
this.context = context;
}
public override IValidator CreateInstance(Type validatorType)
{
return context.Resolve(validatorType) as IValidator;
}
}
Run Code Online (Sandbox Code Playgroud)
我如何提供上下文并注册 ValidatorFactory
FluentValidation.Mvc.FluentValidationModelValidatorProvider.Configure(x => x.ValidatorFactory = new ValidatorFactory());
Run Code Online (Sandbox Code Playgroud) 题
下面的代码工作正常,Server而不是客户端.为什么?
当我提交表格时,控制BeAValidDate功能会检查日期是否有效.Validate没有去服务器使用,有没有办法约会Fluent Validation?
脚本
<script src="jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="jquery.validate.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.js" type="text/javascript"></script>
Run Code Online (Sandbox Code Playgroud)
模型
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(x => x.FromDate)
.NotEmpty()
.WithMessage("Date is required!")
.Must(BeAValidDate)
.WithMessage("Invalid Date");
}
private bool BeAValidDate(String value)
{
DateTime date;
return DateTime.TryParse(value, out date);
}
}
Run Code Online (Sandbox Code Playgroud)
调节器
public class PersonController : Controller
{
public ActionResult Index()
{
return View(new Person { FromDate = DateTime.Now.AddDays(2).ToString()});
}
[HttpPost]
public ActionResult Index(Person p) …Run Code Online (Sandbox Code Playgroud) 我在我的WebApi项目控制器中成功实现了FluentValidation,该控制器只有一个HttpGet方法.当我添加另一个HttpGet方法时,我将路由属性添加到两个方法中.即[Route("Method1")]和[Route("Method2")].
现在无论我是否输入任何数据,ModelState都会返回true.
这是我的代码.
WebApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new ValidateModelStateFilter());
//FluentValidation
FluentValidationModelValidatorProvider.Configure(config);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{action}/{id}",
defaults: new { controller = "Menu", id = RouteParameter.Optional}
);
}
}
Run Code Online (Sandbox Code Playgroud)
ValidateModelStateFilter
public class ValidateModelStateFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
}
Run Code Online (Sandbox Code Playgroud)
调节器
[HttpGet]
[Route("Method1")]
public IHttpActionResult ReadAllMenusByApplication([FromUri] ReadAllMenusByApplicationInput input)
{
var result = new List<ApplicationMenu>();
...
} …Run Code Online (Sandbox Code Playgroud) 我有一个MediatR管道行为,如下所示:
public class FailFastRequestBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
private readonly IEnumerable<IValidator> _validators;
public FailFastRequestBehavior(IEnumerable<IValidator<TRequest>> validators)
{
_validators = validators;
}
public Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var failures = _validators
.Select(async v => await v.ValidateAsync(request))
.SelectMany(result => result.Result.Errors)
.Where(f => f != null);
return failures.Any()
? Errors(failures)
: next();
}
...
}
Run Code Online (Sandbox Code Playgroud)
像这样的MediatR命令:
public class MyUseCase
{
public class Command : IRequest<CommandResponse>
{
...
}
public class Validator : AbstractValidator<Command>
{
...
}
public class Handler<T>: …Run Code Online (Sandbox Code Playgroud) 我有以下 DTO:
public class SomethingRequest {
public string Code { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Code 必须是唯一的,所以我创建了一个验证器来检查是否已经有提供代码的记录,如下所示
public class SomethingValidator: AbstractValidator<SomethingRequest>
{
public SomethingValidator(ISomethingRepository repo) {
RuleFor(something => something.Code).Must(BeUnique);
}
private bool BeUnique(string code) { ... uniqueness check... }
}
Run Code Online (Sandbox Code Playgroud)
当我使用验证功能时,验证器会自动连接到所有带有 的方法SomethingRequest,这真的很棒。
当条件失败时,我想返回409 ConflictHTTP 状态代码,但400 Bad Request总是返回。
所以,问题是:
400 BadRequest验证器的状态代码吗?在负责验证的类内部我有简单的规则:
RuleFor(u => u.Id)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotEmpty().WithMessage("Id is required")
.Must(ValidateId);
Run Code Online (Sandbox Code Playgroud)
下面是我的ValidateId功能:
private bool ValidateId(CreateAccountBindingModel model, string id, PropertyValidatorContext context)
{
if (id=="test")
{
context.Rule.CurrentValidator.ErrorCodeSource = new StaticStringSource("You are testing");
return false;
}
var idValid = IdValidator.IsValid(id);
if (!idValid)
{
context.Rule.CurrentValidator.ErrorCodeSource = new StaticStringSource("Id is invalid");
return false;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
如果我运行我的验证器,我会得到默认错误,而不是我在函数中指定的自定义错误。
我尝试使用以下方法设置它们:
context.Rule.CurrentValidator.ErrorCodeSource = new StaticStringSource("Id is invalid");
Run Code Online (Sandbox Code Playgroud)
但没有任何运气。
如何在验证函数中定义错误消息?
关注点分离 (SoC)
在 ConfigureServices 中注册的依赖指令(启动类的方法)由不同的 DI 组成,如 Repository、Fluent Validations 等。
我将如何将 DI 注册分成单独的文件(如下所示)
c# dependency-injection separation-of-concerns repository-pattern fluentvalidation
我有 WebAPI (.NET Core) 并用于FluentValidator验证模型,包括更新。我使用 PATCH 动词并有以下方法:
public IActionResult Update(int id, [FromBody] JsonPatchDocument<TollUpdateAPI> jsonPatchDocument)
{
Run Code Online (Sandbox Code Playgroud)
另外,我有一validator堂课:
public class TollUpdateFluentValidator : AbstractValidator<TollUpdateAPI>
{
public TollUpdateFluentValidator ()
{
RuleFor(d => d.Date)
.NotNull().WithMessage("Date is required");
RuleFor(d => d.DriverId)
.GreaterThan(0).WithMessage("Invalid DriverId");
RuleFor(d => d.Amount)
.NotNull().WithMessage("Amount is required");
RuleFor(d => d.Amount)
.GreaterThanOrEqualTo(0).WithMessage("Invalid Amount");
}
}
Run Code Online (Sandbox Code Playgroud)
并将其映射到类validator中Startup:
services.AddTransient<IValidator<TollUpdateAPI>, TollUpdateFluentValidator>();
Run Code Online (Sandbox Code Playgroud)
但它不起作用。如何编写FluentValidator对我的任务有效的内容?
我正在使用 FluentValidation 和 MediatR PipelineBehavior 来验证 CQRS 请求。我应该如何在单元测试中测试这种行为?
使用FluentValidation 的测试扩展,我仅测试规则。
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public void Should_have_error_when_name_is_empty(string recipeName)
{
validator.ShouldHaveValidationErrorFor(recipe => recipe.Name, recipeName);
}
Run Code Online (Sandbox Code Playgroud)在单元测试中手动验证请求
[Theory]
[InlineData("")]
[InlineData(" ")]
public async Task Should_not_create_recipe_when_name_is_empty(string recipeName)
{
var createRecipeCommand = new CreateRecipeCommand
{
Name = recipeName,
};
var validator = new CreateRecipeCommandValidator();
var validationResult = validator.Validate(createRecipeCommand);
validationResult.Errors.Should().BeEmpty();
}
Run Code Online (Sandbox Code Playgroud)初始化Pipeline行为
[Theory]
[InlineData("")]
[InlineData(" ")]
public async Task Should_not_create_recipe_when_name_is_empty(string recipeName)
{
var createRecipeCommand = new CreateRecipeCommand
{
Name = recipeName
}; …Run Code Online (Sandbox Code Playgroud)我学会了如何使用流畅的验证器我想知道你是否可以帮助我解决问题。我有一个个人系统,在我的控制器中,create post 方法具有以下代码:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create (TicketViewModel model)
{
ICollection <Piece> pieces;
try
{
if (ModelState.IsValid)
{
if (_ticketRepository.GetById (model.Id)! = null)
{
Console.WriteLine ("Ticket already exists!");
}
var _model = _mapper.Map <Ticket> (model);
var count = _ticketRepository.FindAllByPiece (_model);
if (count> 0)
{
ModelState.AddModelError ("", "This ticket already exists for this room. Check the piece, date and time.");
pieces = _pieceRepository.FindAll ();
model.Pieces = pieces;
return View (model);
}
_ticketRepository.Insert (_model);
model.Seats = RegistrationSeats (model.QuantityOfSeats);
return RedirectToAction ("Index"); …Run Code Online (Sandbox Code Playgroud) fluentvalidation ×10
c# ×7
asp.net-core ×2
asp.net-mvc ×2
mediatr ×2
autofac ×1
cqrs ×1
json-patch ×1
linq ×1
patch ×1
servicestack ×1
unit-testing ×1