Just published (GitHub) a C# example for object Validation, for this purpose I decided to use the .NET Reflection and tried to use Generics. I would really like to improve coding, can you please give me for your feedbacks / reviews / improvements and also new features to implement ?
Here's the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace Validation
{
class Data
{
public string EMail { get; set; }
public DateTime DateOfBirth { get; set; }
public object Age { get; set; }
public object PurchasedItems { get; set; }
public object DateLastPurchase { get; set; }
public Data() {
this.EMail = "[email protected]";
this.DateOfBirth = DateTime.Parse("06/06/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 Validation;
using System.Net.Mail;
namespace Validation
{
class Program
{
public static bool coreLogic(object field)
{
return true;
}
public delegate bool Del(object field);
static void Main(string[] args)
{
Data obj = new Data();
Validation v_obj = new Validation(obj);
Dictionary<string, FieldType> y = v_obj.p_validationFields;
y["EMail"] = FieldType.EMail;
y["DateOfBirth"] = FieldType.DateTime;
y["Age"] = FieldType.Integer;
y["PurchasedItems"] = FieldType.Integer;
y["DateLastPurchase"] = FieldType.DateTime;
v_obj.p_hHandlers = new Hashtable();
v_obj.p_hHandlers.Add(FieldType.EMail, (Del)coreLogic);
bool b = v_obj.setValidationFields(y).doValidation();
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Mail;
using System.Reflection;
namespace Validation
{
public enum FieldType
{
NoValidation,
EMail,
DateTime,
Integer
}
public class Validation
{
private object p_obj { get; set; }
public Dictionary<string, FieldType> p_validationFields { get; set; }
public Hashtable p_hHandlers { get; set; }
public Validation(object o)
{
this.p_obj = o;
Dictionary<string, FieldType> d = new Dictionary<string, FieldType>();
foreach (PropertyInfo p in o.GetType().GetRuntimeProperties())
d.Add(p.Name, FieldType.NoValidation);
this.p_validationFields = d;
}
public Validation setValidationFields(Dictionary<string, FieldType> f)
{
this.p_validationFields = f;
return this;
}
public bool doValidation()
{
bool isValid = false;
Dictionary<string, FieldType> d = this.p_validationFields;
foreach (PropertyInfo p in this.p_obj.GetType().GetProperties())
{
FieldType f;
try
{
f = d[p.Name];
if (d.ContainsKey(p.Name))
{
isValid = ValidateField(p.GetValue(this.p_obj, null), f);
if (!isValid)
break;
}
}
catch (Exception e) { isValid = false; }
}
return isValid;
}
private Boolean ValidateField(object field, FieldType type)
{
Boolean valid = false;
switch (type)
{
case FieldType.EMail:
valid = false;
// default validation for EMail
try {
MailAddress m = new MailAddress((string)field);
valid = true; }
catch (FormatException) {
valid = false; }
// override the default validation for EMail
Delegate handler = (Delegate)this.p_hHandlers[FieldType.EMail];
if (handler!=null) valid = (bool)handler.DynamicInvoke(field);
break;
case FieldType.DateTime:
DateTime d; valid = DateTime.TryParse(field.ToString(), out d);
if (d > DateTime.Now) valid = false;
break;
case FieldType.Integer:
int n; bool b = int.TryParse(field.ToString(), out n); valid = b;
break;
case FieldType.NoValidation:
valid = true;
break;
}
return valid;
}
}
}
Look forward being in touch with you :)
string,DateTime, etc. are validated based on different rules. Even things likeMoney,Age, and similar may often be validated quite differently depending on context. I personally have never seen [overly] generalized validation approach. Neither I saw field-level validation to ever be a complete solution. Domain models and what they represent should be in the focus, IMO \$\endgroup\$