ASP:NET MVC字段摘要作为字段本身的验证(递归)

时间:2017-02-07 21:44:20

标签: asp.net-mvc

我在模型中有以下课程:

public partial class OrganizationUnit
{
    public string code{ get; set; }
    public int OrganizationCod { get; set; }
    public string name { get; set; }
    public string ParentUnitCode{ get; set; }
    public int level{ get; set; }
    public string author{ get; set; }
    public System.DateTime CreateDtStmp{ get; set; }
    public int Status { get; set; }
    public decimal weighing { get; set; }
    [ForeignKey("status")]
    public virtual Status UnitStatus { get; set; }
    public virtual Organization Organization { get; set; }
    public virtual ICollection<OrganizationUnit> OrganizationUnit1{ get; set; }
    [ForeignKey("ParentUnitCode")]
    public virtual OrganizationUnit OrganizationUnit2{ get; set; }

    public OrganizationUnit ()
    {
        CreateDtStmp= DateTime.Now;
        author = HttpContext.Current.User.Identity.Name.Substring(4,HttpContext.Current.User.Identity.Name.Length - 4);
    }
}

在插入新记录之前,我需要验证总和(称重)不能超过100,包括尝试的新记录,只考虑具有相同ParentUnit的记录。

这可以在模型中完成还是应该在控制器中完成?

这是保存控制器部分(基本上是由VS自动生成的),考虑到视图会将相应的参数发送给方法:

private SAIM_IPM_DVContext db = new SAIM_IPM_DVContext();
[HttpPost]
[ValidateAntiForgeryToken]        
public ActionResult Create(OrganizationUnit organizationunit)
{
    if (ModelState.IsValid)
    {
        db.OrganizationUnit.Add(organizationunit);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(organizationunit);
}

2 个答案:

答案 0 :(得分:0)

如果OrganizationUnit1是具有相同ParentUnit的所有其他单元的集合,则可以通过实施IValidatableObject在ViewModel中执行检查:

using System.ComponentModel.DataAnnotations;

public partial class OrganizationUnit : IValidatableObject {
    /* properties etc... */

     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
         if (OrganizationUnit1.Sum(o => o.weighing) + this.weighing > 100.0) {
               yield return new ValidationResult(
                   "Sum of weightings would exceed 100.",
                    new[] { "weighing" });
         }
     }
}

请注意,这假设weighing集合中的所有单位都会回发OrganizationUnit1(例如隐藏字段),因此当MVC管道执行此检查时可以访问它(这是在你的POST动作被击中之前完成。

如果此检查失败,则控制器中的ModelState.IsValid将为false。

如果您无法访问Viewmodel中的其他单元,则必须从控制器中的DB中获取它们并在那里执行检查。

答案 1 :(得分:0)

过了一会儿尝试我想出这个解决方案是完美的,但我不确定是最好的做法。这是在控制器类

    public ActionResult Create(OrganizationUnit organizationunit)
            {
                decimal weighingsum= 0;
    foreach (var val in db.OrganizationUnit.Where(t => t.ParentUnitCode== organizationunit.ParentUnitCode))
                {                        
   weighingsum+= val.weighing ;

                }
                weighingsum+= organizationunit.weighing ;
                if (weighingsum > 100)
                {
                    ModelState.AddModelError("", "Weighing sum can not exceed 100 for a Parent Unit");
                }
                else
                {
                    if (ModelState.IsValid)
                    {
                        db.OrganizationUnit.Add(organizationunit);
                        db.SaveChanges();
                        return RedirectToAction("Index");
                    }
                }
    return View(organizationunit);
    }

如果有人想出更好的解决方案,请分享我会很感激。