如何在实现IValidatableobject的类中验证ILIST类属性中的行?

时间:2012-05-22 09:04:05

标签: asp.net-mvc asp.net-mvc-3

我正在将我当前的asp.net站点迁移到mvc 3.旧的asp.net页面实现了转发器控制,可以验证后面代码中的每一行。

我创建了一个Model类并继承了IValidatableObject。见下面的代码:

public class ManageInstitutions : IValidatableObject
{
        public ManageInstitutions() { }

        public int InstitutionID { get; set; }
        public string InstituteName { get; set; }
        public string FName { get; set; }
        public string LName { get; set; }
        public string EAddress { get; set; }

        public IList<InstitutionIPBL> IPDetailsList { get; set; }

        //Validation Function
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            foreach (var item in IPDetailsList)
            {
                 if (item.IPPart1.Length == 0 && item.IPPart2.Length == 0 && item.IPPart3From.Length == 0 && item.IPPart3To.Length == 0 && item.IPPart4From.Length == 0 && item.IPPart4To.Length == 0)
                  {
                        //How to return ValidationResult that will identify which row got an error????????? 
                  }
            }
        }


}

InstitutionIPBL是一个来自旧的asp.net业务层的类。我重新使用这个类来表示我的模型中的属性。

我需要知道如何确定哪一行出错。我使用此语法来检查字段是否有效:Html.ViewData.ModelState.IsValidField("[Field Name]"))

我的问题是如何根据上面代码中所示的注释来识别哪一行出错。

任何?请指教。提前谢谢

1 个答案:

答案 0 :(得分:0)

由于缺乏支持,验证数组和集合在MVC中是一件棘手的事情。

在验证IEnumerable,ICollection,IList等中的单个元素时,您必须在HTML元素中包含每个元素的索引,并在ModelState中包含验证索引(至少作为最常见的解决方法而不必创建自定义模型绑定器。)

因此,如果您的模型如下:

public IList<string> List { get; set; } 

你的标记看起来像这样:

<input type="text" name="List[0]" />
<input type="text" name="List[1]" />
<input type="text" name="List[2]" />

然后您会注意到每个元素都有自己的索引,这是MVC的表单提供程序用来将输入绑定到模型的索引。

因此,当您去编写验证时,您需要确保包含违规元素的索引(为简单起见而扩展代码):

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
        for (int i = 0; i < List.Count; i++) {
            if (string.IsNullOrEmpty(List[i])) {
                yield return new ValidationResult(i + 
                                  ": You forgot to fill in the box.",
                                  new[] { "List[" + i + "]" });
            }  
        }
}

然后当你写出你的验证信息时:

@Html.ValidationMessage("List[1]")

现在,只要实际查找WHICH元素有验证消息,您需要查看ModelState以获取无效元素的键。

ModelState.Where(x => x.Key.StartsWith("List") && x.Value.Errors.Count > 0)
          .Select(x => x.Key);

这样的东西可以变成HtmlHelper,可以通过以下方式访问ModelState:

public static IEnumerable<string> 
      GetValidationMessagesForGroup(this HtmlHelper helper, string keyStart) {
    return helper.ViewData.ModelState.Where(x => x.Key.StartsWith("List")
                         && x.Value.Errors.Count > 0).Select(x => x.Key);
}

并在你的观点中称呼它:

@{
   foreach(string key in Html.GetValidationMessagesForGroup("List")) 
       @Html.ValidationMessageFor(key)
}

对于强类型对象,您需要做的就是键入它们,最后添加属性。

Child[0].FirstName

请务必记住,列表中每个元素的每个属性都有自己的条目。