美文网首页Asp.net core mvc
在控制器中创建动态对象和动态属性并返回Json数据

在控制器中创建动态对象和动态属性并返回Json数据

作者: firechun | 来源:发表于2019-12-29 17:53 被阅读0次

从不同的表中返回不同的数据,字段名称也不相同,一般会写不同的控制器方法对每个表进行操作。但是在这里感觉很烦琐,因为除了数据不同,客户端的业务逻辑完全相同。以后还有可能增加其它表,也需要实现类似的业务逻辑。

想了想,决定采用动态对象来创建动态属性,微软提供了ExpandoObject 这样一个类可以实现我的需求。
先看代码:

/// <summary>
/// 根据查询语句返回json对象
/// </summary>
/// <param name="sql">查询语句</param>
/// <param name="fields">属性列表,属性应包含在查询语句的字段中</param>
/// <returns></returns>
private ActionResult GetDynamicParams(string sql, params string[] fields)
{
    //创建Newtonsoft的json数组对象
    JArray items = new JArray();
    using (var reader = SqlHelper.ExecuteReader(SqlHelper.GetConnString(), CommandType.Text, sql))
    {
        while (reader.Read())
        {
            //动态属性集合
            Dictionary<string, object> properties = new Dictionary<string, object>();
            foreach (var field in fields)
            {
                properties.Add(field, reader[field]);
            }
            //动态对象
            dynamic obj= new System.Dynamic.ExpandoObject();
            //向动态对象中添加属性
            foreach (var prop in properties)
            {
                ((IDictionary<string, object>)obj).Add(prop.Key, prop.Value);
            }
            //创建Newtonsoft的json对象
            JObject jobj = new JObject();
            //从动态对象中读取数据并放入到json对象中
            foreach (var property in (IDictionary<String, Object>)obj)
            {
                jobj.Add(property.Key, property.Value.ToString());
            }
            items.Add(jobj);
        }
    }
    //返回json数据
    return Content(items.ToString());
}

不要问我为什么还在使用SqlDataReader从数据库读取数据,这个不是重点……
ExpandoObject对象可以直接添加动态属性,例如:

dynamic obj= new System.Dynamic.ExpandoObject();
obj.Name = "张三";
obj.Age = 20;
Console.WriteLine(obj.Name);
Console.WriteLine(obj.Age);

//输出
张三
20

但是在这个需求中不能这么做,因为属性名称是动态的,来自于查询结果中的字段,在这里由方法的可变参数fields提供。假设我们调用时是这样:GetDynamicParams(sql,"StyleNo","StyleDesc")
那么要返回如下数据:

[
  {
    StyleNo: "00432",
    StyleDesc: "休闲牛仔裤"
  },
  {
    StyleNo: "00516",
    StyleDesc: "休闲T恤"
  }
]

如果调用GetDynamicParams(sql,"StoreNo","StoreName")
返回数据如下:

[
  {
    StoreNo: "A",
    StoreName: "一号仓库"
  },
  {
    StoreNo: "B",
    StoreName: "二号仓库"
  }
]

ExpandoObject实现了IDictionary<TKey,TValue>接口,可以利用接口的Add方法向对象动态添加属性。

//动态属性集合
Dictionary<string, object> properties = new Dictionary<string, object>();
foreach (var field in fields)
{
    properties.Add(field, reader[field]);
}

首先声明一个键值对集合,根据参数fields的值,将数据库中的数据添加到键值对集合中。

//向动态对象中添加属性
foreach (var prop in properties)
{
    ((IDictionary<string, object>)obj).Add(prop.Key, prop.Value);
}

每个键值对就是一个属性及属性的值,循环完成之后,obj的内容就是这样:

观察动态对象
到这个时候,动态创建对象和属性就已经完成了。
但是obj不能直接序列化成json数据,如果这时候试图返回json数据:return json(obj);会报以下错误:
InvalidCastException: Unable to cast object of type '<GetExpandoEnumerator>d__51' to type 'System.Collections.IDictionaryEnumerator'.

所以我们借助Newtonsoft的JObject对象来生成json数据

//从动态对象中读取数据并放入到json对象中
foreach (var property in (IDictionary<String, Object>)obj)
{
     jobj.Add(property.Key, property.Value.ToString());
}

这个循环把数据从动态对象中读取出来并放到json对象中。因为属性名称是动态的,我们没法使用对象.属性的方式来访问属性的值。如果使用反射,你会发现obj.GetType().GetProperties()的返回值是null,GetProperty(属性名)的返回值也同样是null。因此,还是要利用IDictionary<String, Object>接口来遍历属性及其值。

相关文章

  • 在控制器中创建动态对象和动态属性并返回Json数据

    从不同的表中返回不同的数据,字段名称也不相同,一般会写不同的控制器方法对每个表进行操作。但是在这里感觉很烦琐,因为...

  • ios 动态创建和复用结构

    在iOS开发中,UI对象的创建我一值坚持的动态创建对象。顶部菜单为例根据数据完成UI对象的创建,动态完成和修改。保...

  • JS中动态创建json,并动态为JSON添加属性,属性值

    前言 在做大数据可视化项目以及后台管理系统,我用的都是vue全家桶+element-ui,这些项目中都会用到tab...

  • JS动态的创建对象和添加属性并移除属性

    Javascript中创建一个对象var obj={};何为动态的创建对象?动态也就是说,属性是不确定的。下面动态...

  • 面向对象的JavaScript

    一 创建简单的对象: 二 使用JSON创建对象*对象层级关系嵌套层次很多*在动态方式中定义一个对象 三 创建...

  • 封装jsonp+promise实现跨域「 音乐接口」

    jsonp原理 通过动态创建 标签,src指向数据地址,其中callback参数作为函数名来包裹住JSON数据返回...

  • iOS RunTime 理解

    可以遍历对象的属性 可以动态的添加、修改属性,动态添加、修改、替换方法,动态添加、修改、替换协议 可以动态创建类、...

  • 对象实用操作

    如何避免类动态绑定属性,并避免创建开销 **对象的动态绑定实际上是通过__dict方法实现的,通过实现__slot...

  • es6 对象 笔记

    创建对象 es5 es6 对象的key 对象属性的缩写 对象的动态属性名 对象属性的get()和set() 对象的...

  • JavaScript 模式(二)

    函数基本 1.总体说明 函数是对象,可以动态创建,可以扩展,可作为参数和返回结果,可以拥有属性和方法 函数提供作用...

网友评论

    本文标题:在控制器中创建动态对象和动态属性并返回Json数据

    本文链接:https://www.haomeiwen.com/subject/jrayoctx.html