Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for giving back extra information from a Validate function

Tags:

c#

I have a class Employee. I want to be able to Validate() it before I save it to make sure all the fields have been populated with valid values. The user of the class may call Validate() before they call Save() or they may call Save() directly and Save() will then call Validate() and probably throw an Exception if validation fails.

Now, my (main) question is this;
If my Validate() function returns a simple bool then how do I tell the user of the class what is wrong, i.e. "Email not filled in", "ID not unique" etc. For the purposes of this I just want the error strings to pass to the human user, but the principle is the same if I wanted a list of error codes (except that makes the use of a bitmap more logical).

  • I could use an Out paramater in my Validate function but I understand this is frowned upon.
  • Rather than returning a bool, I could return a string array from my function and just test if it was empty (meaning no errors) - but that seems messy and not right.
  • I could create a Struct just to return from this method, including a bool and a string array with error messages, but just seems clunky.
  • I could return a bitmap of error codes instead of a bool and look it up, but that seems rather excessive.
  • I could create a public property "ValidationErrors" on the object which would hold the errors. However, that would rely on me calling Validate() before reading it or explicitly calling Validate from the Property() which is a bit wasteful.

My specific program is in C# but this looks like a fairly generic "best practice" question and one I am sure I should know the answer to. Any advice gratefully received.

like image 493
flytzen Avatar asked Jun 25 '09 12:06

flytzen


People also ask

What does the Validate method return?

The Validate method validates the specified validation group. After calling the Validate method on a validation group, the IsValid method will return true only if both the specified validation group and the validation group of the control that caused the page to be posted to the server are valid.

What is the purpose of validation?

The purpose of validation, as a generic action, is to establish the compliance of any activity output as compared to inputs of the activity. It is used to provide information and evidence that the transformation of inputs produced the expected and right result.

What is a validation message?

When you have validation enabled, you can receive messages that validate a filter or function expression. You can receive either warnings or errors based on the information that you have specified in your mapping specification.


4 Answers

I could create a Struct just to return from this method, including a bool and a string array with error messages, but just seems clunky.

Why does it seem clunky? Creating an appropriate type to encapsulate the information is perfect. I wouldn't necessarily use a string to encode such information, though. An enum may be better suited.

An alternative would be to subclass the return type and provide an extra child class for every case – if this is appropriate. If more than one failures may be signalled, an array is fine. But I would encapsulate this in an own type as well.

The general pattern could look like this:

class ValidationInfo {
    public bool Valid { get; private set; }
    public IEnumerable<Failure> Failures { get; private set; }
}
like image 152
Konrad Rudolph Avatar answered Nov 15 '22 04:11

Konrad Rudolph


I would probably go for the bitmap-option. Simply

[Flags]
public enum ValidationError {
    None = 0,
    SomeError = 1,
    OtherError = 2,
    ThirdError = 4
}

...and in the calling code, simply:

ValidationError errCode = employee.Validate();
if(errCode != ValidationError.None) {
    // Do something
}

Seems nice and compact to me.

like image 31
Manne Avatar answered Nov 15 '22 05:11

Manne


I would follow the pattern of the TryParse methods and use a method with this signature:

public bool TryValidate(out IEnumerable<string> errors) { ... }

Another option is to pull the validation code out of the object into its own class, possibly building on the Specification pattern.

public class EmployeeValidator
{
    public bool IsSatisfiedBy(Employee candidate) 
    { 
        //validate and populate Errors 
    }
    public IEnumerable<string> Errors { get; private set; }
}
like image 26
Jamie Ide Avatar answered Nov 15 '22 03:11

Jamie Ide


I have found it a good approach to simply have a method (or a property, since C# has nice support for that) which returns all validation error messages in some kind of sensible, easy to use format, such as a list of strings.

This way you can also keep your validate method returning bools.

like image 29
Jani Hartikainen Avatar answered Nov 15 '22 04:11

Jani Hartikainen