我有一个MVC网络项目。根据最佳实践,添加验证规则和业务规则的正确位置在哪里?
验证规则将是必填字段和所需格式。
业务规则将是“此电子邮件已在数据库中使用”
以下是我目前在注册模式中执行此操作的方法:
public class RegisterModel : IValidatableObject
{
[Display(Name = "Email address")]
[Required(ErrorMessage = "The email address is required")]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string Email { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var retVal = new List<ValidationResult>();
using (var entity = new AcademicUniteDatabaseEntities())
{
if (entity.UserProfiles.Any(x => x.UserName == this.Email))
{
retVal.Add(new ValidationResult("Email already exist", new List<string> { "Email" }));
}
}
return retVal;
}
}
这是我的注册管理员:
public ActionResult Register()
{
var model = new RegisterModel();
return this.View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (!this.ModelState.IsValid)
{
return this.View(model);
}
model.CreateAccount();
return this.View("WaitConfirmEmail");
}
为什么我这样做
这是最佳做法吗?
答案 0 :(得分:2)
使用注释验证模型适用于需要验证的小型应用程序,但是当验证规则开始变得越来越复杂并且模型开始变得越来越复杂时,我建议您查看类似{{{}的库。 3}}。
通过属性验证模型的问题是它可能非常混乱,您将开始遭受大量重复;使用像Fluent验证这样的库所获得的好处是:
典型的Fluent验证规则示例:
public class CustomerValidator: AbstractValidator<Customer>
{
public CustomerValidator()
{
RuleFor(customer => customer.Surname).NotEmpty();
RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
RuleFor(customer => customer.Address).Length(20, 250);
RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
}
private bool BeAValidPostcode(string postcode)
{
// custom postcode validating logic goes here
}
}
Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);
bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;
答案 1 :(得分:0)
另一种方法是创建自定义验证器属性。使用您的解决方案,您可能会得到非常大的模型。另一种方法是创建可以插入控制器的静态助手。这里没有正确答案,它只是您组织代码的方式。我倾向于将业务逻辑分布在可以即插即用的自定义属性上。这样你就可以无缝地重构。