关键字:model属性,反射

正文

        model是数据库的映射,在.net web开发中,作为程序的最底层。web开发的一切都是基于数据库的,分了层之后,就基于model了。

为什么要将model键值对化呢?

        众所周知,程序里循环赋值当然比挨个赋值快的多,简单的多。web开发中,处理参数的接收时,往往是挨个字段都要写一个request请求,就像这样:

string name = context.Request["name"];
string pwd = context.Request["pwd"];
string sex= context.Request["sex"];
string tel = context.Request["tel"];
string orderTimes = context.Request["orderTimes"];
Model model = new Model();
model.name = name;
model.pwd = pwd;
model.sex = sex;
model.tel = tel;
model.orderTimes = orderTimes;
....

从上面可以看出,每一行只有字段的名称不一样,为什么不能写个循环呢?因此想当然的会这样写:

for(int i=0;i<model.property.length;i++)
{
property[i].name = context.Request[property[i].name];
}

这样写当然好啊

1.如果增加一个字段,不用改代码。 2.不用复制粘贴多次。3.只要指定model,对所有的model都是通用的。

这样写当然省事好多,可怎么做到将model键值对化呢,怎么去遍历一个类呢?

键值对化只需要知道model类中各个属性的名称就行了,至于数据类型多种多样,c#中也有方法解决。


使用反射和Dictionary将model类键值对化:

第一步、构建model的键值对映射:

 public Dictionary<string, dynamic> map { get; set; }

泛型的第一参数是属性的名称,第二个参数是对应的值。 这个值可以是int,string,bool等类型,只要使用c#中的dynamic关键字,就可以设置该类型在运行时在推断,和var关键字在编译时推断相反。简而言之,就是用dynamic关键字代替所有的类型,object也能做到,但是会有装箱和拆箱的效率问题,所以就没用。详细了解dynamic,请到msdn查看https://msdn.microsoft.com/zh-cn/library/dd264741.aspx

其实循环遍历model也行啊,为什么要用map映射呢,原因在于:使用dynamic关键字,就避免了各种类型的手动转换了。

第二步、通过反射得到一个model的各个属性的名称,注意是属性而不是字段,而且这里的属性名称一定要和数据库中的名称一样。

代码如下:
public Dictionary<string, dynamic> map { get; set; } Model model = new Model();
Type modelType = model.GetType(); foreach (var property in modelType.GetProperties()) //把所有属性名称加在map的key中
{
map.Add(property.Name, null);
}

这时也不用再考虑给model的各个属性赋值,只需要让model的映射map处理参数接收,好处就在于,model遍历是反射,map遍历不是,而且model中

不能为null的属性,这里map也能统一处理为null,好处就在于,页面传来的参数,赋值给map中对应的key的value,如果map中某一项为null,则代表前台没有这

个参数传过来。

public  void HttpRecieve(HttpContext context)
{
foreach(string key in map.Keys)
{
map[key] = context.Request[key] == "" ? null : context.Request[key];
}
}

然而这样写是一定会错的:

原因是c#中Dictionary 泛型不允许在遍历的时候修改遍历集合内的值。

解决方法也很简单:增加一个List数组,遍历的时候遍历List,赋值的时候给Dictionary赋值。

新增List集合定义:

public List<string> modelNames;

改写上面的初始化:

public Dictionary<string, dynamic> map { get; set; }

Model model = new Model();
Type modelType = model.GetType(); foreach (var property in modelType.GetProperties()) //把所有属性名称加在map的key中
{
map.Add(property.Name, null);
modelNames.Add(property.Name); //新增解决Dictionary不能遍历赋值
}

这样model的映射就完成了,这时,你就可以使用map做很多事了。

给SqlParameter类型就很简单了,

public List<SqlParameter> AddPms()
{
List<SqlParameter> pms = new List<SqlParameter>();
foreach (string name in modelNames)
{
if (map.ContainsKey(name) && map[name] != null)
pms.Add(new SqlParameter("@" + name, map[name]));
}
return pms;
}

使用这个函数,就可以使用带参数的SQL语句,很方便的得到页面传来所有的参数。它是通用的,你不必考虑model里属性都叫什么名字,不用一个一个的

复制粘贴。

这里有个问题其实,上述方法处理的只是plain型的参数,如果是图片等文件类型的,可以在请求参数之后手动覆盖map,比如图片上传使用context.Request

是接收不到的,这时只有在这些plain型数据后手动处理。一个表单plain类型多还是图片类型多呢_,是吧。

注意这里没有说非法参数的过滤问题,如数字类型接收到的是字符串类型,肯定会报错啊。非法参数还是要处理的,这是几乎没法避免的,没有固定的范

式,是简单的写个循环解决不了的。

这一节,我们将model映射为map键值对了,下一节介绍将map映射回model的反射机制。

ps: 反射真是个神奇的东西,能让程序变得简单好多。

asp.net web编程开发将model键值对化的更多相关文章

  1. Asp.Net Web API开发微信后台

    如果说用Asp.Net开发微信后台是非主流,那么Asp.Net Web API的微信后台绝对是不走寻常路. 需要说明的是,本人认为Asp.Net Web API在开发很多不同的请求方法的Restful ...

  2. ASP.NET Web Froms开发模式中实现程序集的延迟加载

    延迟加载是一个很大的诱惑,可以达到一些比较好的效果,比如: 1.在实体框架中,由于关联数据的数量和使用时机是不确定的,通过延迟加载,仅在使用的时候去执行关联数据的查询操作,减少无谓的数据查询操作,可以 ...

  3. 微软实战训练营(X)重点班第(1)课:SOA必备知识之ASP.NET Web Service开发实战

    微软实战训练营 上海交大(A)实验班.(X)重点班 内部课程资料 链接:http://pan.baidu.com/s/1jGsTjq2 password:0wmf <微软实战训练营(X)重点班第 ...

  4. 水果项目第3集-asp.net web api开发入门

    app后台开发,可以用asp.net webservice技术. 也有一种重量级一点的叫WCF,也可以用来做app后台开发. 现在可以用asp.net web api来开发app后台. Asp.net ...

  5. [目录]ASP.NET web api开发实战

    第一章:Restful web service v.s. RPC style web service 第二章:ASP.NET web api v.s. WCF v.s. ASP.NET web ser ...

  6. asp.net web系统开发浏览器和前端工具

    1. Firefox浏览器+firebug插件 下载安装Firefox浏览器后,在菜单-附加组件-扩展中,搜索firebug,下载长得像甲虫一样的安装. 在web调试中,直接点击右上角的虫子,即可调出 ...

  7. ASP.NET Web编程

    runat="server"直接回交服务器,处理数据,又以数据加密后的hidden属性的input控件插入回去,实现表单的状态保存 ruant="server" ...

  8. Asp.net Web Api开发Help Page配置和扩展

    为了方面APP开发人员,服务端的接口都应当提供详尽的API说明.但每次有修改,既要维护代码,又要维护文档,一旦开发进度紧张,很容易导致代码与文档不一致. Web API有一个Help Page插件,可 ...

  9. asp.net web core 开发问题汇总(1)

    1   ASP.NET Core 设置默认静态起始页 转载地址:ASP.NET Core 设置默认起始页(如default.html) 注:1  默认情况下ASP.NET Core应用程序时不支持静态 ...

随机推荐

  1. ubuntu自动挂载windows分区和开机自动启动wallproxy

    1. 自动挂载windows分区 ubuntu默认是要点一下相应的盘符才会挂载windows分区的. 今天发现了ubuntu下最简单的自动挂载windows分区的办法.... :) 参考如下方法:ht ...

  2. CentOS 7 之Shell学习笔记

    脚本是个永恒的话题,以前Dos下面也有Shell编程这一说的,比如说BAT文件有人写的好的话,也是瞬间速度变高大上.Linux下面这个应该更占比重了.我看到园子里有位园友做了一个Linux Shell ...

  3. phpcms v9教程 联动搜索在房地产网站开发中的应用

    开发简述:使用phpcms v9系统,修改源文件5个,创建模型:楼盘.出售.出租.中介.小区,增加联动菜单:楼盘,增加用户组:房产中介.实现功能:游客发布信息.会员申请中介.楼盘全方位展示.报名团购. ...

  4. Windows 7 Apache下计算机无法访问局域网网站的问题

    在Windows 7系统下,由于安全限制问题,本机搭建的网站,局域网内其它计算机是无法访问的. 要解决这个问题,只需要在防火墙加入自建规则便可以了,具体步骤如下: 控制面板=>Windows防火 ...

  5. 自己动手开发编译器(五)miniSharp语言的词法分析器

    稍微说明一点,整型常量和上面的标识符的词法,在调用lex.DefineToken时都多传了一个参数.这个参数是可选的描述信息,如果不传会直接使用正则表达式的字符串形式.而标识符的正则表达式有4万多个字 ...

  6. Android开发者须知的几种APP加密方式--备

    作为一个Android开发者,不仅需要使自己的APP功能丰富,便于使用,同时也需要去完善APP的安全性,下面就介绍几种简单而又可靠的加密方法.1.Spongy Castle Spongy Castle ...

  7. SQL Server 2012数据库还原所遇到的问题

    在SQL Server2005及以下版本做数据库备份还原时,需要首先建立数据库,然后才能进行数据库还原操作:而在SQL Server2005以上版本做数据库还原时,不需要建立数据库,可以直接进行数据库 ...

  8. 文件上传[Uploadify]

    Uploadify文件上传插件 Uploadify简单说来,是基于Jquery的一款文件上传插件.它的功能特色总结如下: 支持单文件或多文件上传,可控制并发上传的文件数 在服务器端支持各种语言与之配合 ...

  9. HDU-3665(单源最短路)

    Problem Description XiaoY is living in a big city, there are N towns in it and some towns near the s ...

  10. flume的自定义sink-Kafka

    1.创建一个agent,sink类型需指定为自定义sink        vi /usr/local/flume/conf/agent3.conf        agent3.sources=as1  ...