Here's a C# class as an example for object validation. For this purpose I decided to use .NET reflection and tried to use generics, probably not in the correct way, that's why I'm writing this post. I would really like to improve coding. Can you please give me your feedback / reviews / improvements or also new features to implement?
Please note that this post is already an improvement of this one.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Validation;
using System.Net.Mail;
namespace Validation
{
class Program
{
public static bool CustomValidationLogic(object field)
{
return true;
}
private delegate bool validationDelegate(object field);
static void Main(string[] args)
{
Customer customer = new Customer();
Validation validationApp = new Validation(customer);
Dictionary<string, FieldType> validationFields = validationApp.validationFields;
validationFields["EMail"] = FieldType.EMail;
validationFields["DateOfBirth"] = FieldType.DateTime;
validationFields["Age"] = FieldType.Numeric;
validationFields["PurchasedItems"] = FieldType.Numeric;
validationFields["DateLastPurchase"] = FieldType.DateTime;
validationFields["Age"] = FieldType.Integer;
// the following two lines are optional (override the default validation rule)
validationApp.customValidationHandlers = new Hashtable();
validationApp.customValidationHandlers.Add(FieldType.EMail, (validationDelegate)CustomValidationLogic);
object validationResult = validationApp.setValidationFields(validationFields).doValidation();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace Validation
{
class Customer
{
public object EMail { get; set; }
public object DateOfBirth { get; set; }
public object Age { get; set; }
public object PurchasedItems { get; set; }
public object DateLastPurchase { get; set; }
public Customer() {
this.EMail = "[email protected]";
//this.DateOfBirth = DateTime.Parse("06/06/1981");
this.DateOfBirth = "01/12/1981";
this.Age = "36";
this.PurchasedItems = "3";
this.DateLastPurchase= "06/06/2017";
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Text.RegularExpressions;
namespace Validation
{
public enum FieldType
{
EMail,
DateTime,
Numeric,
Integer
}
public class ValidationResult
{
public bool isValid { get; set; }
public string invalidPropertyName { get; set; }
public string invalidFieldName { get; set; }
public string invalidPropertyValue { get; set; }
public ValidationResult()
{
this.isValid = false;
this.invalidPropertyName = string.Empty;
this.invalidFieldName = string.Empty;
this.invalidPropertyValue = string.Empty;
}
}
public class Validation
{
private object _toBeValidated { get; set; }
public Dictionary<string, FieldType> validationFields { get; set; }
public Hashtable customValidationHandlers { get; set; }
public Validation(object o)
{
this._toBeValidated = o;
Dictionary<string, FieldType> d = new Dictionary<string, FieldType>();
this.validationFields = new Dictionary<string, FieldType>();
}
public Validation setValidationFields(Dictionary<string, FieldType> f)
{
this.validationFields = f;
return this;
}
public ValidationResult doValidation()
{
ValidationResult result = new ValidationResult();
Dictionary<string, FieldType> fields = this.validationFields;
foreach (PropertyInfo property in this._toBeValidated.GetType().GetProperties())
{
FieldType field_type;
field_type = fields[property.Name];
if (fields.ContainsKey(property.Name))
{
var propertyValue = property.GetValue(this._toBeValidated, null);
result.isValid = ValidateField(propertyValue, field_type);
if (!result.isValid)
{
result.invalidPropertyName = property.Name;
result.invalidFieldName = field_type.ToString();
result.invalidPropertyValue = propertyValue.ToString();
break;
}
}
}
return result;
}
private Boolean ValidateField(object field, FieldType type)
{
Boolean isValid = false;
switch (type)
{
case FieldType.EMail:
isValid = (ValidationDefaultRules.ValidateEMail(field) && ValidationCustomRules.ValidateEMail(this, field));
break;
case FieldType.DateTime:
DateTime d;
isValid = DateTime.TryParse(field.ToString(), out d);
if (d > DateTime.Now) isValid = false;
break;
case FieldType.Numeric:
isValid = new Regex(@"^[-+]?(\d*\.)?\d+$").IsMatch(field.ToString());
break;
case FieldType.Integer:
int nAsInteger;
isValid = int.TryParse(field.ToString(), out nAsInteger);
break;
}
return isValid;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Mail;
namespace Validation
{
public class ValidationCustomRules
{
public static bool ValidateEMail(Validation validation, object field)
{
FieldType field_type = FieldType.EMail;
// override the default validation for EMail
if (validation.customValidationHandlers != null)
{
Delegate handler = (Delegate)validation.customValidationHandlers[field_type];
if (handler != null)
return (bool)handler.DynamicInvoke(field);
else
return true;
}
else
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Mail;
namespace Validation
{
public class ValidationDefaultRules
{
public static bool ValidateEMail(object value) {
try
{
MailAddress m = new MailAddress((string)value);
return true;
}
catch (FormatException)
{
return false;
}
}
}
}