Solved

ASP .NET MVC Conditional Validation RequiredIF Question with VB .NET Code

Posted on 2011-09-10
3
930 Views
Last Modified: 2012-06-27
Hello

I have question on ASP .NET MVC's Property validation with conditional validation.

I need to make a custom validation --- conditional validation, and I have two requirement
--------------------------------------------------------------------------------------------
1) if field A has value "Other", then field B is required.

2) if filed A has value "Other" or null(nothing) and field B is filled, then field A's error message will not be shown

How to accomplish this. Please note that the attached C# .NET code I got from this url:

http://blogs.msdn.com/b/simonince/archive/2010/06/04/conditional-validation-in-mvc.aspx

I translated this to VB .NET, but I get compile error, which comes from ViewModel where I state

 <RequiredIf("firstName", "Anna")> _
 Public Property lastName() As String
       
...
...
....
End Property
       
Private m_lastName As String  


The error shows me that too many arguments to Public Sub New

Why am I getting compiled error?

And how to translate this line of C# code to VB .NET?

 yield return new ModelValidationResult { Message = ErrorMessage };

If the above error gets fixed, my next question would be how to modify the code so that second requirement can be achieved, which is

if filed A has value "Other" or null(nothing) and field B is filled, then field A's error message will not be shown






VB .NET Codes:
------------------
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.ComponentModel.DataAnnotations
Imports site.Helpers

Namespace site.Helpers
    Public Class RequiredIfValidator
        Inherits DataAnnotationsModelValidator(Of RequiredIfAttribute)
        Public Sub New(ByVal metaData As ModelMetadata, ByVal context As ControllerContext, ByVal attribute As RequiredIfAttribute)
            MyBase.New(metaData, context, attribute)
        End Sub

        Public Overrides Function GetClientValidationRules() As IEnumerable(Of ModelClientValidationRule)
            Return New ModelClientValidationRule()
        End Function

        Public Overrides Function Validate(ByVal container As Object) As IEnumerable(Of ModelValidationResult)
            Dim field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty)

            '= Metadata.ContainerType.GetProperty(Attribute.DependentProperty
            If field <> Nothing Then
                Dim value As Object = field.GetValue(container, Nothing)
                If value <> Nothing And Attribute.TargetValue = Nothing Or (value.Equals(Attribute.TargetValue)) Then

                    If Not Attribute.IsValid(Metadata.Model) Then
                        'how to translate the below C# .NET line in VB .NET?
                        '  yield return new ModelValidationResult { Message = ErrorMessage };

                    End If

                End If
            End If


            Return container
        End Function
    End Class

End Namespace

VB .NET Codes
-----------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace ConditionalValidation.Validation
{
    public class RequiredIfAttribute : ValidationAttribute
    {
        // Note: we don't inherit from RequiredAttribute as some elements of the MVC
        // framework specifically look for it and choose not to add a RequiredValidator
        // for non-nullable fields if one is found. This would be invalid if we inherited
        // from it as obviously our RequiredIf only applies if a condition is satisfied.
        // Therefore we're using a private instance of one just so we can reuse the IsValid
        // logic, and don't need to rewrite it.
        private RequiredAttribute innerAttribute = new RequiredAttribute();
        public string DependentProperty { get; set; }
        public object TargetValue { get; set; }

        public RequiredIfAttribute(string dependentProperty, object targetValue)
        {
            this.DependentProperty = dependentProperty;
            this.TargetValue = targetValue;
        }

        public override bool IsValid(object value)
        {
            return innerAttribute.IsValid(value);
        }
    }
}
----------------------------------------
ViewModel in VB .NET

<Required(ErrorMessage:="Specify first Name.")> _
        Public Property firstName() As String
            Get
                Return m_firstName
            End Get
            Set(ByVal value As String)
                m_firstName = value
            End Set
        End Property
        Private m_firstName As String

        <RequiredIf("firstName", "Anna")> _
        Public Property lastName() As String
            Get
                Return m_lastName
            End Get
            Set(ByVal value As String)
                m_lastName = value
            End Set
        End Property
        Private m_lastName As String



// So if the last name is Anna, first name is required
------------------------------------------------

Open in new window

0
Comment
Question by:ashley2009
3 Comments
 
LVL 16

Accepted Solution

by:
ToddBeaulieu earned 500 total points
ID: 36523867
I started down that path and ended up with a much simpler solution, IMO.

I use the standard annotations for simple single-field validations, like this:

        [Required]
        [DisplayName("First Name")]
        public string FirstName { get; set; }

I also implement the IValidatableObject interface on the model itself and put more complex validations in the Validate() method, which is automatically called by the MVC framework. I didn't need custom validators. The less odd-ball code you need to write like that, the better and it seems like every example you find out there doesn't work quite right or isn't exactly what you need.


#region Validations

        public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            // If the selected "Other", ensure they entered something in the "other" field
            if (HowDidYouHear == DROP_DOWN_OTHER_SELECTED_LABEL && string.IsNullOrEmpty(HowDidYouHearOther))
                yield return new ValidationResult("x", new string[] { "HowDidYouHearOther" });

            // If the selected "Other", ensure they entered something in the "other" field
            if (FacilityType == DROP_DOWN_OTHER_SELECTED_LABEL && string.IsNullOrEmpty(FacilityTypeOther))
                yield return new ValidationResult("x", new string[] { "FacilityTypeOther" });
        }

        #endregion

Open in new window

0
 
LVL 3

Author Closing Comment

by:ashley2009
ID: 37900438
thanks.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Host asp.net pages 5 25
Replace &lt; with < 14 54
Put window Form inside tab page 10 26
Connection String 16 42
Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

919 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now