创建具有未知 属性 类型的动态对象
Create dynamic object with unknown property types
我想在 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 采用以下格式:
return new
{
sEcho = pageRequest.Echo,
iTotalRecords = report.TotalItems,
iTotalDisplayRecords = report.TotalItems,
sColumns = pageRequest.ColumnNames,
aaData = results
};
我正在处理的部分是将模型项目列表制定为 return 即:
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;
即设置属性类型eg:DateTime
.
让我重复一遍。我想构建一个模型项目列表。这可以是具有任意数量属性的任何模型类型,每个属性可以是任何类型(int、string、bool、DateTime 等)
正如 Luaan 已经评论的那样,Convert.ChangeType
是您问题的答案。
但是,使用它对您没有任何帮助。为什么?因为转换对象值只有在你想将它分配给特定类型的变量时才有用(与 object
相反)。
property.GetValue(item, null)
的基础类型永远不会改变,因此尝试转换它无济于事。
此外,为什么不直接使用 List<Dictionary<string, object>>
甚至 List<object[]>
(我经常将其用于数据传输目的。使用 dynamic
或 [=16 没有意义=]这里。
如果您希望能够动态添加属性,则需要将您的 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);
}
我想在 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 采用以下格式:
return new
{
sEcho = pageRequest.Echo,
iTotalRecords = report.TotalItems,
iTotalDisplayRecords = report.TotalItems,
sColumns = pageRequest.ColumnNames,
aaData = results
};
我正在处理的部分是将模型项目列表制定为 return 即:
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;
即设置属性类型eg:DateTime
.
让我重复一遍。我想构建一个模型项目列表。这可以是具有任意数量属性的任何模型类型,每个属性可以是任何类型(int、string、bool、DateTime 等)
正如 Luaan 已经评论的那样,Convert.ChangeType
是您问题的答案。
但是,使用它对您没有任何帮助。为什么?因为转换对象值只有在你想将它分配给特定类型的变量时才有用(与 object
相反)。
property.GetValue(item, null)
的基础类型永远不会改变,因此尝试转换它无济于事。
此外,为什么不直接使用 List<Dictionary<string, object>>
甚至 List<object[]>
(我经常将其用于数据传输目的。使用 dynamic
或 [=16 没有意义=]这里。
如果您希望能够动态添加属性,则需要将您的 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);
}