📜 ⬆️ ⬇️

How can I check the values ​​entered by the user

In any software products, whether it is a windows-application or a web-site, information from users is often obtained using data entry forms.

Of course, one cannot be absolutely sure that the user will enter exactly what is needed, so all data must be carefully checked.

As a rule, the algorithm for checking this data is the same: “If the value of the field satisfies the requirement, then check the following requirement, otherwise output an error message. Go to check the value of the next field ".
')
In practice, this results in a rather long “if-else” sequence. Personally, I didn’t like it terribly, because it’s difficult at first glance to determine which fields are checked as how and which messages are issued in case of errors. But there may be ten fields in the form, then the verification code is generally delayed. In general, I thought about how to minimize the amount of work and this is what came of it.

I presented the test as converting a value of one type to a value of another type (for example, checking that a chilo field is entered is a conversion of a string to a number). A validation is a function that has the signature of the System.Converter <T, U> delegate.

To check the value, put the wrapper in the class:

public class ValidationStep<T>
{
public T Value { get ; set ; }
}


The essence of the verification lies in the sequential invocation of extension methods for objects of the ValidationStep <T> class, which again return an object of the ValidationStep <T> class. This allows you to create chains of checks. Here is an example of such extension methods:

public static class ValidationExtensions
{
public static ValidationStep<T> Validate<T>( this T value )
{
return new ValidationStep<T> { Value = value };
}
public static ValidationStep<T> Validate<T>( this ValidationStep<T> step,
Predicate<T> predicate, string message)
{
if (predicate(step.Value)) return step;
throw new ValidationException(message);
}
public static ValidationStep<U> Convert<T, U>( this ValidationStep<T> step,
Converter<T, U> converter, string message)
{
try { return converter(step.Value).Validate(); }
catch { throw new ValidationException(message); }
}
}


The first method is used to check objects of any type, the second method checks for compliance with the predicate, and the third for the possibility of converting values ​​from one type to another. You can also write any other checks, for example, if the integer corresponds to a range. The main thing is that in case of unsuccessful validation, a ValidationException should be thrown that contains the message with the error text.

To perform the check itself, you can use the following class, which will deal with the interception of exceptions:

public static class Validation
{
public static bool Validate<T, U>(T value , Converter<T, U> validator,
Action<U> onSuccess, Action<ValidationException> onFailure)
{
try
{
var result = validator( value );
onSuccess(result);
return true ;
}
catch (ValidationException e)
{
onFailure(e);
return false ;
}
}
}


And now about how to use it. Suppose we need to check the text field (tb1) and make sure that an integer is entered into it in the range from 0 to 10. You can do this by:

Validation.Validate(
tb1.Text, value => value.Validate()
.Validate(x => x.Length > 0, " -" )
. Convert (x => Convert .ToInt32(x), " " )
.Validate(x => x >= 0, " " )
.Validate(x => x <= 10, " " ),
v => MessageBox.Show( " : " + v.Value),
e => MessageBox.Show(e.Message));


Considering that there can be more checks, and the number of fields in the form, as a rule, is more than one, this way of checking can be very convenient.

Well, actually, that's all: o)

Source: https://habr.com/ru/post/51131/


All Articles