代码之家  ›  专栏  ›  技术社区  ›  user10479

ASP.NET MVC不同操作的不同验证规则

  •  5
  • user10479  · 技术社区  · 15 年前

    对于不同的操作(例如,用于创建和删除的不同验证规则),验证我的模型的最佳实践是什么?

    谢谢!

    澄清:我认为这需要澄清,因为答案似乎没有解决问题。

    例如,

    创造人 验证具有名称、年龄和电子邮件的未使用 删除人员 确认此人不是家长。业务逻辑规定不能消除父级

    我如何拥有这两种不同的验证方案?

    7 回复  |  直到 15 年前
        1
  •  2
  •   Hennadiy Kurabko    15 年前

    据我所知,您希望对验证规则有更多的控制。您可以手动添加验证规则,如下所述: MVC 2.0 Client validation exposed 这使您能够完全控制如何组织验证、哪些规则附加哪些操作等。

        2
  •  1
  •   Khaja Minhajuddin    15 年前

    使用验证库(如FluentValidation或NHibernate验证程序)进行验证。将此代码移动到模型绑定器中,以便在传递模型时自动进行验证。您可以查看以下与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, "");
                    }
                }
            }
        }
    
        3
  •  1
  •   daveidmx    15 年前

    澄清:我认为这需要澄清,因为答案似乎没有解决问题。

    例如,

    创建具有姓名、年龄和电子邮件未使用的人验证删除人验证该人不是父级。业务逻辑规定不能消除父级

    我如何拥有这两种不同的验证方案?

    “封装变化的内容。”

    实现这一点的一种方法是使用命令模式,并将验证应用于命令而不是实体。这是一个不使用任何验证框架的简单示例,但其思想是相同的。

    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;
        }
    }
    
        4
  •  0
  •   Daniel Robinson    15 年前

    最好使用 Validator Toolkit for ASP.NET MVC

    该工具包生成客户端和服务器端验证代码。

    这是最近的一篇博文 compares different validation techniques and frameworks .

    如果您使用的是jquery,那么 jQuery validation plugin 值得使用。当然,您仍然需要编写自己的服务器端验证(或使用其他框架进行验证)。

        5
  •  0
  •   takepara    15 年前

    如果使用ASP.NET MVC 1,将检查DataAnnotationsModelBinder扩展。system.componentModel.dataAnnotations是非常有用的验证属性框架! 而且ASP.NET MVC 2 DefaultModeBinder支持它。

    http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471

        6
  •  0
  •   Justin Holzer    15 年前

    如果要使用ASP.NET MVC的多个验证框架之一(XVAL、数据注释属性等),并且只验证特定操作的模型字段的子集,最简单的解决方案是使用 [Bind] 属性。

    当然,我可以想到这样一种情况,您可能只想根据模型字段的子集(即 Create action),我想不出这样一种情况,即您希望在两个不同的操作之间对特定字段的验证完全不同。

    下面是一个简单的例子,将一个Person模型对象与数据注释验证器属性结合使用。这个 创造 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
    }
    

    在上面的示例中, 创造 操作将完全忽略 Id 的属性 Person 模型对象。它不会尝试绑定此属性,也不会尝试对其执行任何验证。因为一个人在创建时没有ID,所以这正是您想要的。这个 更新 另一方面,操作将针对模型的所有属性绑定和验证。

    事实上, Bind 在方法参数上指定属性会使代码有点难看。但是,如果 Exclude 列表变长了,你可以添加一些额外的换行符和空白来帮助减少丑陋。

        7
  •  0
  •   C.T.    15 年前

    我认为,对于这种情况,只需在delete的域模型(bll)中编写一些代码来判断是否可以删除某些人,或者在SQL或SP中编写一些代码,并返回一个值,以便在删除完成后专用。