C# Validation – Best Way of Validating Class Properties

ccsvvalidation

Background:

I have a CSV file, which I need to ready and validate each element in each row and create a collection of a class, having valid data.

i.e
CSV File looks like:

   EmpID,FirstName,LastName,Salary
    1,James,Help,100000
    2,Jane,Scott,1000
    3,Mary,Fraze,10000

Class looks like:

public class Employees
{
    public int EmpID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Salary { get; set; }
    public string ErrorReason { get; set; }
}

Here are the validations required for each field:

  • EmpID:

    • Its a mandatory field, hence cannot be null or empty
    • It should be only an integer
    • It should be not more than 2 digits
    • It should be present in database (query that database and check if an employee exits with this empid.
  • FirstName (same validation for LastName):

    • Its a mandatory field, hence cannot be null or empty
    • It should be only alphabets.
    • Not more than 30 characters are allowed
  • Salary:

    • Its a mandatory field, hence cannot be null or empty
    • It should be a decimal.

To achieve this, here is my approach:

  1. Read CSV file row by row
  2. For each element i.e EmpId, FirstName… etc do the required validations by calling individual methods having validation logic.
    eg:
    public bool ValidateIsDecimal(string value) { }
    public bool ValidateIsEmpIdExists(string value) { }
    etc
  3. If valid, fill corresponding property of "Employees" class.
  4. If NOT VALID, fill "ErrorReason" property, with appropriate reason as to what caused the validation to fail.(eg: Required filed was missing or datatype is not decimal etc)
  5. Add this Class to Employees collection (eg: List)

So, my question is, is this the right approach, or is there any other better/cleaner way of validating class properties.

Best Answer

If I needed to input data and capture errors, I would probably do something more like:

public class Employee
{
    public int EmpID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Salary { get; set; }
}

public class ErrorEmployee : Employee
{
    public string[] ErrorReason { get; set; }
}
  1. Read CSV file row by row
  2. For each element i.e EmpId, FirstName... etc do the required validations by calling individual methods having validation logic. eg: public bool ValidateIsDecimal(string value) { } public bool ValidateIsEmpIdExists(string value) { } etc
  3. If valid, fill corresponding property of "Employees" class. Add this Class to Employees collection (eg: List)
  4. If NOT VALID, fill "ErrorReason" property, with appropriate reason as to what caused the validation to fail.(eg: Required filed was missing or datatype is not decimal etc) Add this Class to ErrorEmployees collection (eg: List)

I wouldn't want to pollute the regular Employee (singular, use the plural for a collection of them) object with error messages. As in the note above, check out the FluentValidation library for your validation and capture a list of errors rather than just the first found.