创建具有未知 属性 类型的动态对象

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 应该是任何模型对象的列表,包括其所有相关属性。我一直在尝试将 reflectionExpandoObject 一起使用来完成此解决方案,但无法弄清楚其机制:

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);
}