Defensive data programming Data Annotation

  • Thread starter Thread starter Kareninstructor
  • Start date Start date
K

Kareninstructor

Guest
I just posted an article on Microsoft TechNet Wiki that may be helpful to some here. In short this article (source code) shows a different approach to validating information entered by a user on a Windows Form.

Sample screen

1457830.png

Class behind this form.

Imports System.ComponentModel.DataAnnotations
Imports ValidatorLibrary.Rules

Namespace Entities
Public Class CustomerLogin

''' <summary>
''' User name
''' </summary>
''' <returns></returns>
<Required(ErrorMessage:="{0} is required"), DataType(DataType.Text)>
<StringLength(20, MinimumLength:=6)>
Public Property UserName() As String

<Required(ErrorMessage:="{0} is required"), DataType(DataType.Text)>
Public Property FirstName() As String

<Required(ErrorMessage:="{0} is required"), DataType(DataType.Text)>
Public Property LastName() As String

Public ReadOnly Property FullName() As String
Get
Return $"{FirstName} {LastName}"
End Get
End Property

''' <summary>
''' User password
''' </summary>
''' <returns></returns>
<Required(ErrorMessage:="{0} is required"), DataType(DataType.Text)>
<StringLength(20, MinimumLength:=6)>
<PasswordCheck(ErrorMessage:="Must include a number and symbol in {0}")>
Public Property Password() As String

''' <summary>
''' Confirmation of user password
''' </summary>
''' <returns></returns>
<Compare("Password", ErrorMessage:="Passwords do not match, please try again"),
DataType(DataType.Text)>
<StringLength(20, MinimumLength:=6)>
Public Property PasswordConfirmation() As String

''' <summary>
''' Validate email address
''' </summary>
''' <returns></returns>
''' <remarks>
''' We use regular expressions rather than using DataType(DataType.EmailAddress)
''' for more control.
''' </remarks>
<Required(ErrorMessage:="The Email address is required")>
<RegularExpression("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}",
ErrorMessage:="Invalid Email address")>
Public Property EmailAddress() As String

<ValidatorLibrary.Rules.CreditCard(
AcceptedCardTypes:=ValidatorLibrary.Rules.CreditCardAttribute.CardType.Visa Or
ValidatorLibrary.Rules.CreditCardAttribute.CardType.MasterCard)>
Public Property CreditCardNumber() As String

<Required(ErrorMessage:="Credit card expire month required")>
<Range(1, 12, ErrorMessage:="{0} is required")>
Public Property CreditCardExpireMonth() As Integer

<Required(ErrorMessage:="Credit card expire year required")>
<Range(2019, 2022, ErrorMessage:="{0} is not valid {1} to {2} are valid")>
Public Property CreditCardExpireYear() As Integer

<Required(ErrorMessage:="{0} is required"), DataType(DataType.Text)>
<StringLength(3, MinimumLength:=3)>
Public Property CreditCardCode() As String
End Class
End Namespace

Validation in the form.

Imports WindowsFormsLibrary
Imports BusinessLibrary.Entities
Imports DataLibraryMocked
Imports ValidatorLibrary.LanguageExtensions
Imports ValidatorLibrary.Validators

Public Class LoginForm
Private _retryCount As Integer = 0

Private dataOperations As New DataOperations

Private Sub LoginButton_Click(sender As Object, e As EventArgs) _
Handles LoginButton.Click

Dim login As New CustomerLogin With
{
.UserName = UserNameTextBox.Text,
.Password = PasswordTextBox.Text,
.PasswordConfirmation = PasswordConfirmTextBox.Text,
.EmailAddress = EmailTextBox.Text,
.FirstName = FirstNameTextBox.Text,
.LastName = LastNameTextBox.Text,
.CreditCardNumber = CreditCardTextBox.Text,
.CreditCardExpireMonth = ExpireMonthTextBox.AsInteger,
.CreditCardExpireYear = ExpireYearTextBox.AsInteger,
.CreditCardCode = CreditCardCode.Text
}


Dim validationResult As EntityValidationResult = ValidationHelper.ValidateEntity(login)

If validationResult.HasError Then

If _retryCount >= 3 Then
MessageBox.Show("Guards toss them out!")
Close()
End If

MessageBox.Show(validationResult.ErrorMessageList())
_retryCount += 1

Else
dataOperations.ReadUsers()

Dim testIfUserNameExist = dataOperations.Dictionary.ContainsValue(UserNameTextBox.Text)
If testIfUserNameExist Then
MessageBox.Show("User name already exist, please select a different user name")
Exit Sub
End If

dataOperations.Dictionary.Add(dataOperations.Dictionary.Keys.Max() + 1, UserNameTextBox.Text)
dataOperations.Save()

Dim f As New MainForm(login.FullName)
f.Show()
Hide()
End If

End Sub
Private Sub LoginForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If Environment.UserName = "Karens" Then
TextBoxList.ForEach(Sub(tb) tb.PasswordChar = Nothing)
End If
End Sub
End Class

Article

Source code (on Github)





Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

NuGet BaseConnectionLibrary for database connections.

StackOverFlow
7218100.png

Continue reading...
 
Back
Top