简体   繁体   English

MVC 5构建动态匿名对象

[英]MVC 5 Build a dynamic anonymous object

I am working on an MVC 5 application and trying to allow the user to write their own query and display the results in Jquery DataTables. 我正在研究MVC 5应用程序,并尝试允许用户编写自己的查询并在Jquery DataTables中显示结果。 I am having a hard time figuring out how to dynamically build an Anonymous JSON object depending on the users input. 我很难确定如何根据用户输入动态构建匿名JSON对象。

In theory the user would send over a list of columns and a where clause to build a SQL query. 理论上,用户将发送列列表和where子句以构建SQL查询。 I would run the SQL query like this, and build out my object. 我会像这样运行SQL查询,并构建我的对象。

How do I dynamically build out this "select new { DT_RowId = a.id, name = a.name, number = a.number }" depending on what the user inputs. 如何根据用户输入的内容动态构建“select new {DT_RowId = a.id,name = a.name,number = a.number}”。

var v = (from a in dc.Products.SqlQuery(querystring) select new { DT_RowId = a.id, name = a.name, number = a.number }).ToList();

Ultimately the JSON reponse is 最终JSON响应是

data":[{"id":56,"name":"Product 55","number":"55"}] data“:[{”id“:56,”name“:”Product 55“,”number“:”55“}]

It works fine when hard coded. 它在硬编码时工作正常。 Otherwise I will have to Select * from products and then show/hide columns on the client side, thus making my Data Payload very large if all columns are coming back from server. 否则,我将不得不从产品中选择*,然后在客户端显示/隐藏列,这样如果所有列都从服务器返回,则会使我的数据有效载荷非常大。

Is there a way to loop through the requested properties to build this anonymous object? 有没有办法循环遍历请求的属性来构建这个匿名对象? I tried to use a Dictionary however the Json returned was very different, it had Key and Value in it, and that is not what DataTables is expecting. 我试图使用一个字典但是Json返回的是非常不同的,它有Key和Value,而这并不是DataTables所期望的。

Thanks! 谢谢!

FULL CONTROLLER CODE 完整的控制器代码

using (DataTableExampleContext dc = new DataTableExampleContext())
        {
            var v = (from a in dc.Products.SqlQuery(querystring) select new { DT_RowId = a.id, name = a.name, number = a.number }).ToList();

            recordsTotal = v.Count();
            var data = v.Skip(skip).Take(pageSize).ToList();


            return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data }, JsonRequestBehavior.AllowGet);
        }

Solution Thanks to Phillipe 解决方案感谢Phillipe

        using (DataTableExampleContext dc = new DataTableExampleContext())
        {
            var v = (from a in dc.Products.SqlQuery(querystring) select GetResult(a, ColumnNames)).ToList();

            recordsTotal = v.Count();
            var data = v.Skip(skip).Take(pageSize).ToList();

            return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data }, JsonRequestBehavior.AllowGet);
        }
    }

    public Dictionary<string,object> GetResult(Product p, List<string> columnNames)
    {
        var properties = TypeDescriptor.GetProperties(typeof(Product));
        var dict = new Dictionary<string, object>();

        foreach (var x in columnNames)
        {
            if (x == "id")
            {
                dict["DT_RowId"] = properties[x].GetValue(p);
            }
            else
            {
                dict[x] = properties[x].GetValue(p);
            }

        }
        return dict;
    }

If you're using JSON.NET, a dictionary should serialize with the value of the Key as the property name and the value associated with the key as the property value. 如果您正在使用JSON.NET,则字典应序列化,并将Key的值作为属性名称,并将与键关联的值作为属性值进行序列化。

If you're using the DataContractJsonSerializer, you will want to provide the setting UseSimpleDictionaryFormat as true. 如果您正在使用DataContractJsonSerializer,则需要将UseSimpleDictionaryFormat设置为true。

You would then build your dictionary with the name of the property as a key, and the value as the value. 然后,您将使用属性的名称作为键来构建字典,并将值作为值。 If the user selects that they want the name, you would do something like outputDict.Add(nameof(x.Name), x.Name); 如果用户选择他们想要的名称,你会做类似outputDict.Add(nameof(x.Name), x.Name); then return the dictionary to be serialized by your serialization library. 然后返回序列化库序列化的字典。

1/ To get the values of the properties from their name, you can use property descriptors: 1 /要从名称中获取属性的值,可以使用属性描述符:

var properties = TypeDescriptor.GetProperties(typeof(Product));
var value = properties[name].GetValue(product);

2/ To build the answer, you can create a dynamic object: 2 /要构建答案,您可以创建一个dynamic对象:

dynamic result = new ExpandoObject();
var dict = (IDictionary<string,object>)result;
dict[name] = value;

The result can then be converted to JSON. 然后可以将result转换为JSON。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM