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);
}

如果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。

如果您无法访问视图模型中的其他单元,则必须从控制器中的数据库中获取它们并在那里执行检查。

一段时间后,我尝试了一下,我想出了这个解决方案,效果很好,但我不确定是最佳实践。这是在控制器类上

    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);
    }

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

最新更新