Consider using data annotations.
For a simple example, validate user name and password (along with password confirmation)
using System.ComponentModel.DataAnnotations;
using ValidateLoginCore.Classes.ValidationRules;
namespace ValidateLoginCore.Classes
{
public class CustomerLogin
{
/// <summary>
/// User name
/// </summary>
/// <returns>User name for login</returns>
[Required(ErrorMessage = "{0} is required"), DataType(DataType.Text)]
[StringLength(10, MinimumLength = 6)]
public string UserName { get; set; }
/// <summary>
/// User password which must match PasswordConfirmation using
/// PasswordCheck attribute
/// </summary>
/// <returns>plain text password</returns>
[Required(ErrorMessage = "{0} is required"), DataType(DataType.Text)]
[StringLength(20, MinimumLength = 6)]
[PasswordCheck(ErrorMessage = "Must include a number and symbol in {0}")]
public string Password { get; set; }
/// <summary>
/// Confirmation of user password
/// </summary>
/// <returns>plain text password</returns>
[Compare(
"Password",
ErrorMessage = "Passwords do not match, please try again"),
DataType(DataType.Text)]
[StringLength(20, MinimumLength = 6)]
public string PasswordConfirmation { get; set; }
public override string ToString() => UserName;
}
}
Custom attribute
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
namespace ValidateLoginCore.Classes.ValidationRules
{
public class PasswordCheck : ValidationAttribute
{
public override bool IsValid(object value)
{
var validPassword = false;
var reason = string.Empty;
var password = (value == null) ? string.Empty : value.ToString();
if (string.IsNullOrWhiteSpace(password) || password.Length < 6)
{
reason = "new password must be at least 6 characters long. ";
}
else
{
var pattern = new Regex("((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})");
if (!pattern.IsMatch(password))
{
reason += "Your new password must contain at least 1 symbol character and number.";
}
else
{
validPassword = true;
}
}
if (validPassword)
{
return true;
}
else
{
return false;
}
}
}
}
Here when there is an issue we present a message box. For bonus points we could have this information show up in labels which for WPF requires a tad bit more code.
Say we want to validate an SSN passed the usual validation on length
using System;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
namespace ValidationCoreLibrary.CommonRules
{
/// <summary>
/// Is a valid SSN
/// </summary>
/// <returns>True if valid, false if invalid SSN</returns>
/// <remarks>
///
/// Handle some commonly encountered “fake” values or ones that might easily be forged in
/// an area that might require a user to enter one.
///
/// ^ #Start of expression
/// (?!\b(\d)\1+-(\d)\1+-(\d)\1+\b) #Don't allow all matching digits for every field
/// (?!123-45-6789|219-09-9999|078-05-1120) #Don't allow "123-45-6789", "219-09-9999" or "078-05-1120"
/// (?!666|000|9\d{2})\d{3} #Don't allow the SSN to begin with 666, 000 or anything between 900-999
/// - #A dash (separating Area and Group numbers)
/// (?!00)\d{2} #Don't allow the Group Number to be "00"
/// - #Another dash (separating Group and Serial numbers)
/// (?!0{4})\d{4} #Don't allow last four digits to be "0000"
/// $ #End of expression
/// </remarks>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class SocialSecurityAttribute : ValidationAttribute
{
//public string SocialValue { get; set; }
public override bool IsValid(object value) =>
value is string && Regex.IsMatch(value.ToString().Replace("-", ""),
@"^(?!\b(\d)\1+\b)(?!123456789|219099999|078051120)(?!666|000|9\d{2})\d{3}(?!00)\d{2}(?!0{4})\d{4}$");
}
}
In a class usage
public class Person
{
/// <summary>
/// First name
/// </summary>
[Required(ErrorMessage = "{0} is required"), DataType(DataType.Text)]
[StringLength(20, MinimumLength = 6)]
public string FirstName { get; set; }
/// <summary>
/// Last name
/// </summary>
[Required(ErrorMessage = "{0} is required"), DataType(DataType.Text)]
[StringLength(10)]
public string LastName { get; set; }
/// <summary>
/// Phone number
/// </summary>
[Required(ErrorMessage = "{0} is required"), DataType(DataType.Text)]
[Phone]
public string Phone { get; set; }
/// <summary>
/// Social Security number
/// </summary>
[SocialSecurity] public string SSN { get; set; }
public override string ToString() => $"{FirstName} {LastName} {SSN}";
}