Nhibernate.Validator, jQuery and xVal

Jul 28, 2009 at 8:34 PM

Hello,

I'm having some trouble getting these to play nice together. 

I have a user class, which has an address that is a nhibernate user type.    The regular fields in the user class all validate nicely on the client side,  but the fields in the adress don't.    I threw a html.ValidationSummary on the view to see if anything was seeing the rules on the address class fields and It filled up with them.  I'm not sure what that means in terms of where the problem is.  

 

Here's the user Class:

Imports NHibernate.Validator
Public Class User


    Private m_FirstName As String
    Private m_LastName As String
    Private m_Age As String


    Private m_Address As Address

     <NotNullNotEmpty(message:="First Name is Required"), Length(min:=2, max:=30, message:="First Name must be between 2 and 30 characters")> _
    Public Property FirstName() As String
        Get
            Return m_FirstName
        End Get
        Set(ByVal value As String)
            m_FirstName = value
        End Set
    End Property

    <NotNullNotEmpty(message:="Last Name is Required"), Length(min:=2, max:=30, message:="Last Name must be between 2 and 30 characters")> _
    Public Property LastName() As String
        Get
            Return m_LastName
        End Get
        Set(ByVal value As String)
            m_LastName = value
        End Set
    End Property

     <NotNullNotEmpty(message:="Age is Required"), Range(min:=1, max:=120, message:=" Age must be between 1 and 120")> _
    Public Property Age() As String
        Get
            Return m_Age
        End Get
        Set(ByVal value As String)
            m_Age = value
        End Set
    End Property

    <Valid()> _
    Public Property Address() As Address
        Get
            Return m_Address
        End Get
        Set(ByVal value As Address)
            m_Address = value
        End Set
    End Property


End Class


And the Address Class:
Public Class Address

    Private m_Line1 As String
    Private m_Line2 As String
    Private m_PostalCode As String
    Private m_Country As String
    Private m_Province As String

    <NotNullNotEmpty(message:="Line 1 is Required"), Length(min:=7, max:=30, message:="Line 1 must be between 7 and 30 characters")> _
        Public Property Line1() As String
        Get
            Return m_Line1
        End Get
        Set(ByVal value As String)
            m_Line1 = value
        End Set
    End Property

    <Length(min:=5, max:=20, message:="Line 2 must be betwee 5 and 20 characters")> _
       Public Property Line2() As String
        Get
            Return m_Line2
        End Get
        Set(ByVal value As String)
            m_Line2 = value
        End Set
    End Property

    <NotNullNotEmpty(message:="PostalCode is Required"), Length(min:=6, max:=10, message:="Postal Code must be between 6 and 10 characters")> _
        Public Property PostalCode() As String
        Get
            Return m_PostalCode
        End Get
        Set(ByVal value As String)
            m_PostalCode = value
        End Set
    End Property

    <NotNullNotEmpty(message:="Country is Required"), Length(min:=2, max:=30, message:="Country must be between 2 and 30 characters")> _
        Public Property Country() As String
        Get
            Return m_Country
        End Get
        Set(ByVal value As String)
            m_Country = value
        End Set
    End Property

    <NotNullNotEmpty(message:="Province is Required"), Length(min:=2, max:=15, message:="Province must be between 2 and 15 characters")> _
        Public Property Province() As String
        Get
            Return m_Province
        End Get
        Set(ByVal value As String)
            m_Province = value
        End Set
    End Property


End Class


And the Index.aspx View
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of RoutingStuff.User)" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Index
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Index</h2>

  <%=""%>
    <% Using Html.BeginForm() %>
<%=Html.ValidationSummary%>
        
            <p>
                <label for="FirstName">FirstName:</label>
                <%=Html.TextBox("theuser.FirstName")%>
                
            </p>
            <p>
                <label for="LastName">LastName:</label>
                <%=Html.TextBox("theuser.LastName")%>
                
            </p>
            <p>
                <label for="Age">Age:</label>
                <%=Html.TextBox("theuser.Age")%>
                
            </p>
            
            <p>
                <label for="Address.Line1">Line 1</label>
                <%=Html.TextBox("theuser.Address.Line1")%>
            </p>
            <p>
                <label for="Address.Line2">Line2</label>
                <%=Html.TextBox("theuser.Address.Line2")%>
            </p>
            <p>
                <label for="Address.PostalCode">Postal Code</label>
                <%=Html.TextBox("theuser.Address.PostalCode")%>
            </p>
            <p>
                <label for="Address.Country">Country</label>
                <%=Html.TextBox("theuser.Address.Country")%>
            </p>
            <p>
                <label for="Address.Province">Province</label>
                <%=Html.TextBox("theuser.Address.Province")%>
            </p>
            
            <p>
                <input type="submit" value="Save" />
            </p>
        
   <%=Html.ClientSideValidation(Of RoutingStuff.User)("theuser")%>
    <%=Html.ClientSideValidation(Of RoutingStuff.Address)("theuser.Address")%>
    <% End Using %>



</asp:Content>


Anyone have any ideas?

Thanks!


Jul 30, 2009 at 2:45 PM
Edited Jul 30, 2009 at 3:32 PM

So: I've figured it out,  for the most part.  It looks like it was just cofused about the names  in these:

<%=Html.ClientSideValidation(Of RoutingStuff.Address)("theuser.Address")%>

Edit: the . should be replaced with a _  to get the client side stuff working.


I now have the client side validation working for the sub-class, except for the one custom validation, which only fires on the server side, and when it does, the message returned only goes in the validation summary, not by the field.

Here's the updated View and the controllers:
    <AcceptVerbs(HttpVerbs.Get)> _
    Function Index() As ActionResult
        Dim u As New User
        Dim a As New Address
        a.Country = "Canada"
        a.PostalCode = "A1a1A1"
        a.Province = "Ontario"
        a.Line1 = "3350 South Service Rd"
        a.Line2 = "Burlington"
        u.FirstName = "Bob"
        u.LastName = "Barker"
        u.Address = a


        Return View(u)

    End Function

    <AcceptVerbs(HttpVerbs.Post)> _
    Function Index(ByVal theuser As User) As ActionResult

        Validate(theuser)
        If ModelState.IsValid() Then
            'yay
            Return Content("it worked")
        Else
            'awwww

            Return View(theuser)
        End If


    End Function


The View:

<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of RoutingStuff.User)" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Index
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Index</h2>

  <%=""%>
    <% Using Html.BeginForm() %>
<%=Html.ValidationSummary%>
        
            <p>
                <label for="FirstName">FirstName:</label>
                <%=Html.TextBox("FirstName")%>
                
            </p>
            <p>
                <label for="LastName">LastName:</label>
                <%=Html.TextBox("LastName")%>
                
            </p>
            <p>
                <label for="Age">Age:</label>
                <%=Html.TextBox("Age")%>
                
            </p>
            
            <p>
                <label for="Address.Line1">Line 1</label>
                <%=Html.TextBox("Address.Line1")%>
            </p>
            <p>
                <label for="Address.Line2">Line2</label>
                <%=Html.TextBox("Address.Line2")%>
            </p>
            <p>
                <label for="Address.PostalCode">Postal Code</label>
                <%=Html.TextBox("Address.PostalCode")%>
            </p>
            <p>
                <label for="Address.Country">Country</label>
                <%=Html.TextBox("Address.Country")%>
            </p>
            <p>
                <label for="Address.Province">Province</label>
                <%=Html.TextBox("Address.Province")%>
            </p>
            <p>
                I agree to the terms:<%=Html.CheckBox("terms", False)%>
            </p>
            
            <p>
                <input type="submit" value="Save" />
            </p>
        
   <%=Html.ClientSideValidation(Of RoutingStuff.User)()%>
    <%=Html.ClientSideValidation(Of RoutingStuff.Address)("Address")%>
    <% End Using %>



</asp:Content>

So, I hope this helps someone who gets stuck on this in the future. And if anyone knows how to get the results of a custom validation to show up by the field instead of only in the summary let me know!