最近在修改維護以前的webform項目(維護別人開發的.....)整個aspx沒有用到任何的控件,這個我也比較喜歡不用控件
所以在提交信息的時候需要自己手動的去Request.QueryString[]或者Request.Form[]去獲取,轉型,判定等等
覺得這樣子的代碼寫多了不甚其煩,就在想能不能自動獲取,解析這些參數成我需要的數據實體呢,當然是可以的
這里我用反射根據參數的Key與實體的PropertyName進行對比,類型轉換賦值給實體
public static T NameValues2Entity<T>(NameValueCollection NVS)
{
if (!NVS.HasKeys()) return default(T);
T entity = Activator.CreateInstance<T>();
PropertyInfo[] attrs = entity.GetType().GetProperties();
foreach (PropertyInfo p in attrs)
{
foreach (string key in NVS.AllKeys)
{
if (string.Compare(p.Name, key, true) == 0)
{
p.SetValue(entity, Convert.ChangeType(NVS[key], p.PropertyType), null);
}
}
}
return entity;
}
獲取的時候直接調用NameValues2Entity<Model.Article>(Request.Form)即可獲取Model.Article的數據實體,當然反射里面我沒有做數據類型轉化失敗的判定,也只是簡單的數據類型驗證,如果需要復雜的數據類型驗證,這里自己遞歸一下。
同時這里可以自行擴展,做個數據驗證,神馬必填,范圍,正則等等,通過AOP來實現(通過對實體字段定義自定義屬性達到數據驗證)!
傳遞數據的搞定了,現在我們來做做讀取數據的
如果你還是用的ADO.NET讀取數據的時候全部是DataSet,DataTable
你需要得到其實體(ViewModel)或者需要對其實體進行序列化,(默認情況下DataTable無法進行Json序列化)
可以自己根據DataTable的數據類型定義一個實體,但是自己手動轉換還得判定DbNull的情況
這里我們也通過反射實現一個
public static List<T> DataTable2Entities<T>(DataTable table)
{
if (null == table || table.Rows.Count <= 0) return default(List<T>);
List<T> list = new List<T>();
List<string> keys = new List<string>();
foreach (DataColumn c in table.Columns)
{
keys.Add(c.ColumnName.ToLower());
}
for (int i = 0; i < table.Rows.Count; i++)
{
T entity = Activator.CreateInstance<T>();
PropertyInfo[] attrs = entity.GetType().GetProperties();
foreach (PropertyInfo p in attrs)
{
if (keys.Contains(p.Name.ToLower()))
{
if (!DBNull.Value.Equals(table.Rows[i][p.Name]))
{
p.SetValue(entity, Convert.ChangeType(table.Rows[i][p.Name], p.PropertyType), null);
}
}
}
list.Add(entity);
}
return list;
}
這個里面已經自動對DBNull的情況做了判定
調用時候直接var model=DataTable2Entities<Model.Article>(dt);即可
