我想在ASP.NET MVC应用程序上创建一个通用的服务器端DataTable解决方案。我在每个Index
视图上拥有的是一个JQuery数据表,其中对控制器进行AJAX调用以检索分页数据结果。执行的操作如下:
public JsonResult GetNewRequests([ModelBinder(typeof(DataTablesModelBinder))] DataTablesPageRequest pageRequest)
{
var page = RequestsQuery(pageRequest); // Retrieves page of result from db and does any filtering + sorting
var pageResponse = DataTablesFormat.PageResponse(pageRequest, page); // Formats response for jQuery DataTable to use
return Json(pageResponse, JsonRequestBehavior.AllowGet); // Returns result
}
返回到jQuery DataTable控件的响应采用以下格式:
return new
{
sEcho = pageRequest.Echo,
iTotalRecords = report.TotalItems,
iTotalDisplayRecords = report.TotalItems,
sColumns = pageRequest.ColumnNames,
aaData = results
};
我正在研究的部分是制定要返回的模型项列表,即:
aaData = results
results
应该是任何模型对象的列表,包括其所有相关属性。我一直在尝试将reflection
与ExpandoObject
一起使用来完成此解决方案,但无法找出机制:
public static object PageResponse(DataTablesPageRequest pageRequest, Page<object> report)
{
List<object> results = new List<object>();
foreach(var item in report.Items)
{
dynamic dynamicObject = new ExpandoObject();
Type type = item.GetType();
PropertyInfo[] properties = type.GetProperties();
foreach(PropertyInfo property in properties)
{
Type propertyType = property.PropertyType;
// Here is where I want to add a property with the correct name of the required type to the dynamic object
dynamicObject[property.Name] = property.GetValue(item, null) as propertyType;
}
results.Add(dynamicObject);
}
return new
{
sEcho = pageRequest.Echo,
iTotalRecords = report.TotalItems,
iTotalDisplayRecords = report.TotalItems,
sColumns = pageRequest.ColumnNames,
aaData = results
};
}
即使在打字时我也想出了一些东西。这部分我无法弄清楚:
dynamicObject[property.Name] = property.GetValue(item, null) as propertyType;
即设置属性类型,例如:DateTime
。
让我再说一遍。我想构建一个模型项列表。这可以是任何具有任意数量属性的模型类型,每个属性可以是任何类型(int,string,bool,DateTime等)。
答案 0 :(得分:1)
正如Luaan已经评论过的那样,Convert.ChangeType
就是你问题的答案。
但是,使用此功能对您来说无济于事。为什么?因为如果要将对象值分配给特定类型的变量(与object
相对),则只有转换对象值才有用。
property.GetValue(item, null)
的基础类型永远不会改变,因此尝试施放它无济于事。
另外,为什么不使用List<Dictionary<string, object>>
甚至List<object[]>
(我经常将其用于数据传输目的。使用dynamic
或ExpandoObject
没有意义这里。
答案 1 :(得分:1)
如果您希望能够动态添加属性,则需要将expando转换为IDictionary<string, object>
:
foreach(var item in report.Items)
{
dynamic dynamicObject = new ExpandoObject();
var dic = dynamicObject as IDictionary<string, object>;
var properties = item.GetType().GetProperties();
foreach(PropertyInfo property in properties)
{
dic[property.Name] = property.GetValue(item, null);
}
// At this stage the dynamicObject will contain properties with correct
// names and types
results.Add(dynamicObject);
}