字段名为空space时,如何使用toList反序列化数据表?
How to use toList to deserialize datatable when there is a field name with empty space?
我有一个 Datatable
像下面的结构,
[
{
"Product P/N": "12",
"Brand": "A"
},
{
"Product P/N": "34",
"Brand": "B"
}
]
然后,我试着把它做成TableData
。但是 Product P/N
全部为空。
var table = this.DataTable.ToList<TableData>();
var a = table.FirstOrDefault().ProductPN; // null
var b = table.FirstOrDefault().Brand; // A
数据表扩展:
public static List<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
IList<T> result = new List<T>();
foreach (var row in table.Rows)
{
var item = MappingItem<T>((DataRow)row, properties);
result.Add(item);
}
return result.ToList();
}
Class:
public class TableData
{
[JsonProperty(PropertyName = "Product P/N")]
public string ProductPN{ get; set; }
public string Brand { get; set; }
}
映射项
private static T MappingItem<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (var property in properties)
{
var PtName = property.Name;
if (!string.IsNullOrEmpty(property.ToDescription()) && row.Table.Columns.Contains(property.ToDescription()))
{
PtName = property.ToDescription();
}
if (row.Table.Columns.Contains(PtName))
{
if (property.PropertyType == typeof(string))
{
if (row[PtName] != null && row[PtName] != DBNull.Value)
{
property.SetValue(item, row[PtName].ToString(), null);
}
else
{
property.SetValue(item, string.Empty, null);
}
}
else if (property.PropertyType == typeof(bool))
{
if (row[PtName].ToString().ToUpper() == "TRUE")
{
property.SetValue(item, true, null);
}
else
{
property.SetValue(item, false, null);
}
}
else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?))
{
DateTime dt = new DateTime();
if (row[PtName] != DBNull.Value && DateTime.TryParse(row[PtName].ToString(), out dt))
{
property.SetValue(item, dt, null);
}
else
{
property.SetValue(item, null, null);
}
}
else if (property.PropertyType == typeof(decimal))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, val, null);
}
else if (property.PropertyType == typeof(decimal?))
{
if (row[PtName] == DBNull.Value || row[PtName].ToString() == null)
{
property.SetValue(item, null, null);
}
else
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, val, null);
}
}
else if (property.PropertyType == typeof(double))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, Convert.ToDouble(val), null);
}
else if (property.PropertyType == typeof(Int16))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, Convert.ToInt16(val), null);
}
else if (property.PropertyType == typeof(Int32))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, Convert.ToInt32(val), null);
}
else if (property.PropertyType == typeof(Int64))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, Convert.ToInt64(val), null);
}
else
{
if (row[PtName] != DBNull.Value)
{
property.SetValue(item, row[PtName], null);
}
}
}
}
return item;
}
ToDescription():
public static string ToDescription(this PropertyInfo Object)
{
object[] attrs = Object.GetCustomAttributes(typeof(Display), false);
if (null != attrs && attrs.Length > 0) return ((Display)attrs[0]).Text;
return Object.Name.ToString();
}
我怎样才能真正获得带有 space 或特殊字符的名称字段?
对于您的 ProductPN
属性,您应用的 JsonProperty
属性不是 ToDescription()
方法中的 Display
属性。
因此您将获得默认的 属性 名称。
解决方案
为避免中断现有的 ToDescription()
方法,您需要应用此逻辑:
- 从
JsonPropertyAttribute
检索属性。
- 从
DisplayAttribute
检索属性。
- Return默认
Property.Name
.
using Newtonsoft.Json;
public static string ToDescription(this PropertyInfo property)
{
try
{
object[] descriptionAttrs = property.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (descriptionAttrs != null && descriptionAttrs.Length > 0)
{
JsonPropertyAttribute description = (JsonPropertyAttribute)descriptionAttrs[0];
return description.PropertyName;
}
object[] attrs = property.GetCustomAttributes(typeof(DisplayAttribute), false);
if (null != attrs && attrs.Length > 0)
return ((DisplayAttribute)attrs[0]).Name;
return property.Name.ToString();
}
catch
{
return null;
}
}
我有一个 Datatable
像下面的结构,
[
{
"Product P/N": "12",
"Brand": "A"
},
{
"Product P/N": "34",
"Brand": "B"
}
]
然后,我试着把它做成TableData
。但是 Product P/N
全部为空。
var table = this.DataTable.ToList<TableData>();
var a = table.FirstOrDefault().ProductPN; // null
var b = table.FirstOrDefault().Brand; // A
数据表扩展:
public static List<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
IList<T> result = new List<T>();
foreach (var row in table.Rows)
{
var item = MappingItem<T>((DataRow)row, properties);
result.Add(item);
}
return result.ToList();
}
Class:
public class TableData
{
[JsonProperty(PropertyName = "Product P/N")]
public string ProductPN{ get; set; }
public string Brand { get; set; }
}
映射项
private static T MappingItem<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (var property in properties)
{
var PtName = property.Name;
if (!string.IsNullOrEmpty(property.ToDescription()) && row.Table.Columns.Contains(property.ToDescription()))
{
PtName = property.ToDescription();
}
if (row.Table.Columns.Contains(PtName))
{
if (property.PropertyType == typeof(string))
{
if (row[PtName] != null && row[PtName] != DBNull.Value)
{
property.SetValue(item, row[PtName].ToString(), null);
}
else
{
property.SetValue(item, string.Empty, null);
}
}
else if (property.PropertyType == typeof(bool))
{
if (row[PtName].ToString().ToUpper() == "TRUE")
{
property.SetValue(item, true, null);
}
else
{
property.SetValue(item, false, null);
}
}
else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?))
{
DateTime dt = new DateTime();
if (row[PtName] != DBNull.Value && DateTime.TryParse(row[PtName].ToString(), out dt))
{
property.SetValue(item, dt, null);
}
else
{
property.SetValue(item, null, null);
}
}
else if (property.PropertyType == typeof(decimal))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, val, null);
}
else if (property.PropertyType == typeof(decimal?))
{
if (row[PtName] == DBNull.Value || row[PtName].ToString() == null)
{
property.SetValue(item, null, null);
}
else
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, val, null);
}
}
else if (property.PropertyType == typeof(double))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, Convert.ToDouble(val), null);
}
else if (property.PropertyType == typeof(Int16))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, Convert.ToInt16(val), null);
}
else if (property.PropertyType == typeof(Int32))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, Convert.ToInt32(val), null);
}
else if (property.PropertyType == typeof(Int64))
{
decimal val = new decimal();
decimal.TryParse(row[PtName].ToString(), out val);
property.SetValue(item, Convert.ToInt64(val), null);
}
else
{
if (row[PtName] != DBNull.Value)
{
property.SetValue(item, row[PtName], null);
}
}
}
}
return item;
}
ToDescription():
public static string ToDescription(this PropertyInfo Object)
{
object[] attrs = Object.GetCustomAttributes(typeof(Display), false);
if (null != attrs && attrs.Length > 0) return ((Display)attrs[0]).Text;
return Object.Name.ToString();
}
我怎样才能真正获得带有 space 或特殊字符的名称字段?
对于您的 ProductPN
属性,您应用的 JsonProperty
属性不是 ToDescription()
方法中的 Display
属性。
因此您将获得默认的 属性 名称。
解决方案
为避免中断现有的 ToDescription()
方法,您需要应用此逻辑:
- 从
JsonPropertyAttribute
检索属性。 - 从
DisplayAttribute
检索属性。 - Return默认
Property.Name
.
using Newtonsoft.Json;
public static string ToDescription(this PropertyInfo property)
{
try
{
object[] descriptionAttrs = property.GetCustomAttributes(typeof(JsonPropertyAttribute), false);
if (descriptionAttrs != null && descriptionAttrs.Length > 0)
{
JsonPropertyAttribute description = (JsonPropertyAttribute)descriptionAttrs[0];
return description.PropertyName;
}
object[] attrs = property.GetCustomAttributes(typeof(DisplayAttribute), false);
if (null != attrs && attrs.Length > 0)
return ((DisplayAttribute)attrs[0]).Name;
return property.Name.ToString();
}
catch
{
return null;
}
}