Solved

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

Posted on 2011-09-10
3
941 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

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
MediaHelp 4 21
Store results in vb.net 3 20
VB.net and sql server 4 33
How come this regular expression allows "e"? 14 35
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

786 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