为不同的操作验证模型的最佳做法是什么,例如,创建和删除的验证规则不同?
谢谢!
澄清:我认为这需要一些澄清,因为答案似乎没有解决这个问题。
例如,
创建人物 没有使用名称,年龄和电子邮件的验证 删除人 验证Person不是Parent。商业逻辑决定父母不能被淘汰
我如何拥有这两种不同的验证方案?
答案 0 :(得分:2)
据我了解,您希望更好地控制验证规则。您可以按照此处的说明手动添加验证规则:MVC 2.0 Client validation exposed这使您可以完全控制如何组织验证,哪些规则添加了哪些操作等。
答案 1 :(得分:1)
使用FluentValidation或NHibernate Validators等验证库进行验证。将此代码移动到模型绑定器中,以便无论何时传递模型,它都会自动进行验证。您可以查看以下使用FluentValidation
的模型绑定器public class FluentValidationModelBinder : DefaultModelBinder {
private readonly IValidatorFactory _validatorFactory;
public FluentValidationModelBinder(IValidatorFactory validatorFactory) {
_validatorFactory = validatorFactory;
}
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) {
var model = bindingContext.Model;
base.OnModelUpdated(controllerContext, bindingContext);
IValidator validator = _validatorFactory.GetValidator(bindingContext.ModelType);
if (validator != null) {
var result = validator.Validate(model);
if (!result.IsValid) {
result.AddToModelState(bindingContext.ModelState, "");
}
}
}
}
答案 2 :(得分:1)
澄清:我认为这需要一些澄清,因为答案似乎没有解决这个问题。
例如,
创建人员名称,年龄和电子邮件未使用的验证删除人员验证人员不是父级。商业逻辑决定父母不能被淘汰
我如何拥有这两种不同的验证方案?
“封装变化的内容。”
实现此目的的一种方法是使用Command模式,并将验证应用于Command而不是Entity。这是一个简单的例子,没有使用任何验证框架,但想法是一样的。
public class Blub
{
public int BlubId { get; set; }
public string Name { get; set; }
public bool SomeBlockingCondition { get; set; }
}
public class BlubEditController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Rename(int blubId)
{
var ctx = new DataContext();
var blub = ctx.Blubs.Single(o => o.BlubId==blubId);
return ShowRenameForm(blub);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Rename(int blubId, RenameCommand cmd)
{
var ctx = new DataContext();
var blub = ctx.Blubs.Single(o => o.BlubId==blubId);
cmd.Subject = blub;
if (cmd.Validate(ModelState, "cmd."))
{
cmd.Execute();
ctx.SubmitChanges();
return RedirectToAction("Show", new { blubId = blubId });
}
else
{
return ShowRenameForm(blub);
}
}
}
public class RenameCommand
{
public Blub Subject { get; set; }
public string Name { get; set; }
public bool Validate(ModelStateDictionary modelState, string prefix)
{
if (Subject.SomeBlockingCondition)
{
modelState.AddModelError(prefix + "SomeBlockingCondition", "No!");
return false; // Optional shortcut return to prevent further validation.
}
if (String.IsNullOrEmpty(this.Name))
{
modelState.AddModelError(prefix + "Name", "Seriously, no.");
}
return modelState.IsValid;
}
public void Execute()
{
Subject.Name = this.Name;
}
}
答案 3 :(得分:0)
最好使用Validator Toolkit for ASP.NET MVC
此工具包生成客户端和服务器端验证代码。
最近有一篇博文compares different validation techniques and frameworks。
如果您正在使用jQuery,那么jQuery validation plugin值得使用。当然,您仍然需要编写自己的服务器端验证(或使用其他框架)。
答案 4 :(得分:0)
如果使用ASP.NET MVC 1,则将检查DataAnnotationsModelBinder扩展。 System.ComponentModel.DataAnnotations是非常有用的验证属性框架! ASP.NET MVC 2 DefaultModebinder支持它。
http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471
答案 5 :(得分:0)
如果要使用ASP.NET MVC的几个验证框架之一(xVal,Data Annotations属性等)并且仅验证特定操作的模型字段的子集,最简单的解决方案是使用{ {3}}属性。
虽然我当然可以想到一个案例,你可能只想对模型字段的一个子集进行验证(即在Create
动作中),但我想不出你想要验证的情况。一个特定的领域在两个不同的行动之间完全不同。
这是一个简单的例子,将Person模型对象与Data Annotations验证器属性结合使用。 Create
和Update
操作将针对不同的模型字段进行验证。
的模型强>:
public class Person
{
[Required]
Int32 Id { get; set; }
[Required]
String FirstName {get; set;}
[Required]
String LastName {get; set;}
}
控制器操作:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create( [Bind(Exclude = "Id")] Person person )
{
// this action will not perform any validation checks against the Id property of the model
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update( Person person )
{
// this action will perform validation checks against all model properties, including Id
}
在上面的示例中,Create
操作将完全忽略Id
模型对象的Person
属性。它不会尝试绑定此属性,也不会尝试对其执行任何验证。由于Person在创建时没有Id,这正是您想要的。另一方面,Update
操作将绑定并验证模型的所有属性。
在method参数上指定Bind
属性这一事实可能会使代码变得丑陋。但是,如果Exclude
列表变长,您可以随时添加一些额外的换行符和空格,以帮助减少丑陋。
答案 6 :(得分:0)
我认为,对于这种情况,只需在DELETE的域模型(BLL)中编写一些代码来判断是否可以删除某些Person,或者在sql或sp中写入一些代码并返回值如果删除完了。