我正在尝试包含复杂视图模型的项目的FluentValidation,我在这里阅读文档,但我没有看到如何设置规则来验证在我的视图模型中声明的对象列表.在下面的示例中,视图模型中的列表包含一个或多个Guitar对象.谢谢
查看模型
[FluentValidation.Attributes.Validator(typeof(CustomerViewModelValidator))]
public class CustomerViewModel
{
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "Phone")]
public string Phone { get; set; }
[Display(Name = "Email")]
public string EmailAddress { get; set; }
public List<Guitar> Guitars { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
View Model中使用的吉他类
public class Guitar
{
public string Make { get; set; }
public string Model { get; set; …Run Code Online (Sandbox Code Playgroud) 我有具有名称字段的类别模型,并且每个类别名称必须是唯一的.我已经进行了验证,当我尝试创建新的类别时,它可以正常工作,但在尝试编辑时遇到问题.现在只是检查名称是否存在,当然我在尝试编辑同一类别时也是如此.
模型
[Validator(typeof(CategoryValidator))]
public class Category
{
public int ID { get; set; }
public string Name { get; set; }
virtual public ICollection<Image> Images { get; set; }
}
public class CategoryValidator : AbstractValidator<Category>
{
public CategoryValidator()
{
RuleFor(x => x.Name).NotEmpty().WithMessage("Category name is required.").Must(UniqueName).WithMessage("This category name already exists.");
}
private bool UniqueName(string name)
{
ProjecteDataContext _db = new ProjecteDataContext();
var category = _db.Categories.Where(x => x.Name.ToLower() == name.ToLower()).SingleOrDefault();
if (category == null) return true;
return false;
}
} …Run Code Online (Sandbox Code Playgroud) 以下是我的问题的简化版本.
我不能压扁模型.我需要一个"孩子"列表来验证生日.
我似乎无法在Parent类中引用日期,并想知道如何在Fluent验证中完成此操作?
模型
[Validator(typeof(ParentValidator))]
public class Parent
{
public string Name { get; set; }
public DateTime Birthdate { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public string ChildProperty{ get; set; }
public DateTime Birthdate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
验证器
public class ParentValidator : AbstractValidator<Parent>
{
public ParentValidator()
{
RuleFor(model => model.Name).NotEmpty();
RuleForEach(model => model.Children).SetValidator(new ChildValidator());
}
}
public class ChildValidator : AbstractValidator<Child>
{
public ChildValidator()
{
RuleFor(model => model.ChildProperty).NotEmpty(); …Run Code Online (Sandbox Code Playgroud) 在我的WebAPI项目中,我Owin.Security.OAuth用来添加JWT身份验证.GrantResourceOwnerCredentials我的OAuthProvider 内部使用以下行设置错误:
context.SetError("invalid_grant", "Account locked.");
Run Code Online (Sandbox Code Playgroud)
这将返回给客户:
{
"error": "invalid_grant",
"error_description": "Account locked."
}
Run Code Online (Sandbox Code Playgroud)
在用户获得身份验证并且他尝试向我的某个控制器执行"正常"请求后,当模型无效时,他会得到以下响应(使用FluentValidation):
{
"message": "The request is invalid.",
"modelState": {
"client.Email": [
"Email is not valid."
],
"client.Password": [
"Password is required."
]
}
}
Run Code Online (Sandbox Code Playgroud)
这两个请求都在返回400 Bad Request,但有时您必须查找error_description字段,有时候还要查找message
我能够创建自定义响应消息,但这仅适用于我返回的结果.
我的问题是:是否有可能取代message与error响应由返回ModelValidatorProviders,并在其他地方?
我读过ExceptionFilterAttribute但我不知道这是不是一个好的起点.FluentValidation应该不是问题,因为它只是添加错误ModelState.
编辑:
我正在尝试解决的下一件事是WebApi中返回的数据中的命名约定不一致 - 当OAuthProvider我们返回错误error_details时,但是当我们返回BadRequest时ModelState(从ApiController)返回错误modelState.正如你可以看到第一次使用snake_case …
我正在使用FluentValidation来验证一个对象,因为这个对象有一个我正在尝试使用的集合成员RuleForEach.例如,假设我们有Customer和Orders,并且我们希望确保没有客户订单的总价值超过该客户允许的最大值:
this.RuleForEach(customer => customer.Orders)
.Must((customer, orders) => orders.Max(order => order.TotalValue) <= customer.MaxOrderValue)
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是,我还需要记录有关错误上下文的其他信息(例如,在数据文件中找到错误的位置).我发现使用FluentValidation很难实现这一点,到目前为止我最好的解决方案是使用该WithState方法.例如,如果我发现客户的地址详细信息不正确,我可能会这样做:
this.RuleFor(customer => customer.Address)
.Must(...)
.WithState(customer => GetErrorContext(customer.Address))
Run Code Online (Sandbox Code Playgroud)
(GetErrorContext我的方法在哪里提取相关细节.
现在我遇到的问题是,在使用时RuleForEach,方法签名假定我将提供一个引用验证失败Customer的特定表达式,而不是Order导致验证失败的特定表达式.我似乎无法分辨哪个订单有问题.因此,我无法存储适当的上下文信息.
换句话说,我只能这样做:
this.RuleForEach(customer => customer.Orders)
.Must((customer, orders) => orders.Max(order => order.TotalValue) <= customer.MaxOrderValue)
.WithState(customer => ...)
Run Code Online (Sandbox Code Playgroud)
......当我真的想要这样做时:
this.RuleForEach(customer => customer.Orders)
.Must((customer, orders) => orders.Max(order => order.TotalValue) <= customer.MaxOrderValue)
.WithState(order => ...)
Run Code Online (Sandbox Code Playgroud)
是否真的无法访问失败的集合项的详细信息(甚至索引)?
我想另一种看待它的方式是我想WithState拥有一个等价物WithStateForEach......
我用了Fluent Validator.但有时我需要创建一个规则层次结构.例如:
[Validator(typeof(UserValidation))]
public class UserViewModel
{
public string FirstName;
public string LastName;
}
public class UserValidation : AbstractValidator<UserViewModel>
{
public UserValidation()
{
this.RuleFor(x => x.FirstName).NotNull();
this.RuleFor(x => x.FirstName).NotEmpty();
this.RuleFor(x => x.LastName).NotNull();
this.RuleFor(x => x.LastName).NotEmpty();
}
}
public class RootViewModel : UserViewModel
{
public string MiddleName;
}
Run Code Online (Sandbox Code Playgroud)
我想从UserValidation继承验证规则到RootValidation.但是这段代码不起作用:
public class RootViewModelValidation:UserValidation<RootViewModel>
{
public RootViewModelValidation()
{
this.RuleFor(x => x.MiddleName).NotNull();
this.RuleFor(x => x.MiddleName).NotEmpty();
}
}
Run Code Online (Sandbox Code Playgroud)
如何使用FluentValidation继承验证类?
最初在为字符串编写验证逻辑时,我决定使用NotEmpty来处理所需的任何字符串.当使用.NotEmpty().Length(min,max)时,这将导致返回两个错误,而不是在传入空字符串时返回一个错误.
如何防止冗余错误?
我正在使用FluentValidation来验证我的服务操作.我的代码看起来像:
using FluentValidation;
IUserService
{
void Add(User user);
}
UserService : IUserService
{
public void Add(User user)
{
new UserValidator().ValidateAndThrow(user);
userRepository.Save(user);
}
}
Run Code Online (Sandbox Code Playgroud)
UserValidator实现FluentValidation.AbstractValidator.
DDD表示域层必须与技术无关.
我正在做的是使用验证框架而不是自定义异常.
将验证框架放在域层中是一个坏主意吗?
c# architecture domain-driven-design repository fluentvalidation
我正在使用内置容器ASP.NET Core和支持"行为"管道的 MediatR 3 :
public class MyRequest : IRequest<string>
{
// ...
}
public class MyRequestHandler : IRequestHandler<MyRequest, string>
{
public string Handle(MyRequest message)
{
return "Hello!";
}
}
public class MyPipeline<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next)
{
var response = await next();
return response;
}
}
// in `Startup.ConfigureServices()`:
services.AddTransient(typeof(IPipelineBehavior<MyRequest,str??ing>), typeof(MyPipeline<MyRequest,string>))
Run Code Online (Sandbox Code Playgroud)
我需要在管道中使用FluentValidation验证器.在MediatR 2中,创建了一个验证管道:
public class ValidationPipeline<TRequest, TResponse>
: IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
public …Run Code Online (Sandbox Code Playgroud) 我在ASP.net MVC 3中有以下视图:
@model Models.CreateProjectViewModel
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
@using( Html.BeginForm() ) {
@Html.TextBoxFor(m => m.ProjectName)
@Html.ValidationMessageFor(m => m.ProjectName)
<p>
<input type="submit" value="Save" />
</p>
}
Run Code Online (Sandbox Code Playgroud)
我正在使用不引人注目的javascript与jQuery和Fluent验证框架.
当我单击"保存"按钮并且验证失败时,是否有一些事件我可以挂钩调用一些自定义的JavaScript?
function validationFailed() {
// do something here only if validation failed
}
Run Code Online (Sandbox Code Playgroud)
我如何与验证绑定,以便在失败时(并且只有失败)我可以调用validationFailed()函数.
asp.net-mvc asp.net-mvc-validation fluentvalidation unobtrusive-validation asp.net-mvc-3
fluentvalidation ×10
c# ×8
asp.net-mvc ×3
validation ×3
.net ×1
architecture ×1
asp.net ×1
asp.net-core ×1
c#-4.0 ×1
cqrs ×1
mediatr ×1
owin ×1
repository ×1
string ×1