0

Consider the following @razor page:

 For i as Integer = 0 to 4
      @Html.TextBoxFor(Function(model) model.Skills(i).Name)  
      @Html.TextBoxFor(Function(model) model.Skills(i).Title)
      @Html.ValidationMessageFor(Function(model) model.Skills(i).Name)
 Next
 @Html.ValidationMessageFor(Function(model) model.Skills)  // <- This one doesnt display validation error message !!

And the following model:

 ' Model
 <MinLength(10)>  // this validation runs but (above) doesn't show error messsage
 Public Property Skills As SkillsObj()

How do I get @Html.ValidationMessageFor(Function(model) model.Skills) to display an error message? It doesn't even though I'm performing validation on the Skills array (and validation is executing). I do see the error messages for @Html.ValidationMessageFor(Function(model) model.Skills(i).Name) which run other validations.

  • How have you created your custom validation attribute for the collection? And its not binding to `Skills[x].Name`. For that you need `@Html.ValidationMessageFor(Function(model) model.Skills(i).Name)` –  Sep 13 '14 at 06:30
  • Thats correct, that works. I'm looking to get the error message on the ARRAY itself not just the elements within. –  Sep 13 '14 at 06:33
  • In my example above, I'm trying to validate the MinLength of the Skills array and that error message (should it be less than the min) won't show. –  Sep 13 '14 at 06:39
  • I hope this link should help you (the way to wireup a custom validation and getting it to the clientside): http://stackoverflow.com/questions/4747184/perform-client-side-validation-for-custom-attribute/4747466#4747466 – Siva Gopal Sep 13 '14 at 06:43
  • I'm not sure I understand how you are doing this. How have you created a validation attribute for that? Does it support client side validation? Have you rendered some kind of input for `model.Skills` so the validation can match to a property? –  Sep 13 '14 at 06:44
  • The validation attribute isn't relevant, it can be any, the builtin or custom. If I have the following: Public Property Skills as MySkills() and MySkills has two properties (say) Name as String and Title as String. I want show that in my page, so, I loop over TextBoxFor(Function(m) m.Skills{x].Name) and TextBoxFOr(Function(m) m.Skills[x].Title -- that properly outputs my text fields (From a FOR loop). When I press the submit button Skills[x].Name and Skills[x].Title all post back just fine and I can run validation on them, BUT I want to run validation on the SKILLS array itself (too) [Cont...] –  Sep 13 '14 at 06:50
  • when I do, validation DOES work, but it DOESN'T display the error message. I don't know why its not displaying the error message. I can however display the error messages for my array elements Skills[x].Name and Skills[x].Title –  Sep 13 '14 at 06:51
  • Siva Gopal I think you've completely misunderstood my question. –  Sep 13 '14 at 06:53
  • @JasonCaldwell, If you have a look at the html you will see that it renders ``. If you don't have an input with the same name ("Skills") with the relevant `data-` validation attributes it wont work. If you only want to validate on the server you can use the `ModelState.AddModelError` method and return the view –  Sep 13 '14 at 07:16
  • I've simplified my original post to hopefully make it clearer. –  Sep 13 '14 at 07:20

1 Answers1

0

Though I am not sure if the following sample code answer your exact problem but it perfectly works for array item length validation using DataAnnotations attribute:

Model

Imports System.ComponentModel.DataAnnotations

Public Class MyCustomObjectWithArray
    <MinLength(4, ErrorMessage:="Minimum four Employees should be submitted.")>
    Public Property EmployeeArray() As Employee()
End Class

Public Class Employee

    Public Property Name() As String

    Public Property City() As String

End Class

Controller

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Function Index() As ActionResult

        Dim customObject As MyCustomObjectWithArray = New MyCustomObjectWithArray()
        customObject.EmployeeArray = New Employee() {}

        'Fill the employee array to have only 3 elements so that
        '       validation fail on form post since Employee array has validation for at least 4 employee names.
        For empIndex = 0 To 2
            ReDim Preserve customObject.EmployeeArray(empIndex)
            customObject.EmployeeArray(empIndex) = New Employee()
        Next

        Return View("CreateEmployees", customObject)
    End Function

    <HttpPost>
    Function CreateEmployees(ByVal objWithArray As MyCustomObjectWithArray) As ActionResult

        If (Not ModelState.IsValid) Then    'Make sure modelstate validation errors are not bypassed.
            Return View("CreateEmployees", objWithArray)
        End If

        'Do stuff like saving to DB or whatever you want with the valid Posted data.

        Return RedirectToAction("Index", "Home")
    End Function
End Class

View

@ModelType MvcVBApplication.MyCustomObjectWithArray

@Code
    ViewData("Title") = "CreateEmployees"
End Code

<h3>CreateEmployees<h3>

    @Using (Html.BeginForm("CreateEmployees", "Home"))

        Html.EnableClientValidation(True)
        @<table>
            @If (Model.EmployeeArray IsNot Nothing) Then

            For empIndex = 0 To Model.EmployeeArray.Count() - 1
                @<tr>
                    <td>
                        @Html.TextBoxFor(Function(modelItem) Model.EmployeeArray(empIndex).Name)
                    </td>
                </tr>
            Next

        Else
                @Html.TextBox("(0).Name", "")
        End If
        </table>
        @Html.ValidationMessageFor(Function(m) m.EmployeeArray)
        @<br />
        @<input type="submit" name="name" value="Submit" />
    End Using

Hope this helps. I am not much into VB.NET so you may choose appropriate code constructs if you find the one I use seem to be in old way.

Siva Gopal
  • 3,474
  • 1
  • 25
  • 22