ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改

   ASP.NET MVC+EF框架+EasyUI实现权限管系列

  

   (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装 

   (5):前台Jquery easyUI实现    (6):EF上下文实例管理    (7):DBSession的封装   (8):DBSession线程内唯一  

   (9):TT摸版的学习   (10):VSS源代码管理

  前言:上篇博客我们简单的说了一下源代码管理工具(VSS)的使用,相信大家看完之后都能够会使用VSS源代码管理工具,在源代码管理工具中VSS算是最简单的,没有什么难度,就是重点理解签入,签出和回滚的含有以及如何操作。那么这篇博客我们开始讲述如何实现用户的登录以及对前面博友们的评论提出修改底层的东西进行了一次修改还有验证码的使用。那么下面我首先要说的是前面网友提出的一个小的修改。

1.Func<T, bool>和Expression<Func<T, bool>>的使用区别

  (1)在前面我写ASP.NET MVC+EF框架+EasyUI实现权限管理系列(4)-业务逻辑曾的封装(http://www.cnblogs.com/hanyinglong/archive/2013/04/09/3011119.html)这篇博客的时候,有一位博友(@Qlin)提出了我在项目底层些查询的时候为什么不用Expression<Func<T,bool>>,因为当时我实现的代码是Func<T,bool> wherelambda来定义的,当时的代码如下:

 1         //实现对数据库的查询  --简单查询
 2         IQueryable<T> LoadEntities(Func<T, bool> whereLambda);
 3
 4         /// <summary>
 5         /// 实现对数据的分页查询
 6         /// </summary>
 7
 8         /// <typeparam name="S">按照某个类进行排序</typeparam>
 9
10         /// <param name="pageIndex">当前第几页</param>
11
12         /// <param name="pageSize">一页显示多少条数据</param>
13
14         /// <param name="total">总条数</param>
15
16         /// <param name="whereLambda">取得排序的条件</param>
17
18         /// <param name="isAsc">如何排序,根据倒叙还是升序</param>
19
20         /// <param name="orderByLambda">根据那个字段进行排序</param>
21
22         /// <returns></returns>
23
24         IQueryable<T> LoadPageEntities<S>(int pageIndex, int pageSize, out int total, Func<T, bool> whereLambda,  bool isAsc, Func<T, S> orderByLambda);

  (2)那么根据那位博友提出来的意见,我查看资料,发现他们还真的有很大的区别,这里我就简单的说一下他们的区别,并且非常感谢博友们能提出这样的问题,希望广大博友们能真心的提出来项目中的问题,我将虚心接受。

  (3)那么他们有什么区别呢?网上的资料是这样说的,Func<T,bool>本身就是一个委托(delegate),而Expression<Func<T,bool>>确实一个表达式,只有在编译之后才会变成委托,那么在EF中到底使用哪一个呢?又是为什么呢?其实如果我们写成Func<T,bool>类型的便来那个如果作为参数传递给where方法进行Linq查询时,Entity FrameWork将会产生全表查询,将整个数据库表忠的数据加载到内存中,然后再内存中根据where中的条件进一步查询,而Expression<Func<t,bool>>只是查询出来你where条件中的数据,不用去进行全表查询,所以我们修改后的代码是:   

 1  //实现对数据库的查询  --简单查询
 2
 3         IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda);
 4
 5         /// <summary>
 6
 7         /// 实现对数据的分页查询
 8
 9         /// </summary>
10
11         /// <typeparam name="S">按照某个类进行排序</typeparam>
12
13         /// <param name="pageIndex">当前第几页</param>
14
15         /// <param name="pageSize">一页显示多少条数据</param>
16
17         /// <param name="total">总条数</param>
18
19         /// <param name="whereLambda">取得排序的条件</param>
20
21         /// <param name="isAsc">如何排序,根据倒叙还是升序</param>
22
23         /// <param name="orderByLambda">根据那个字段进行排序</param>
24
25         /// <returns></returns>
26
27         IQueryable<T> LoadPageEntities<S>(int pageIndex, int pageSize, out int total, Expression<Func<T, bool>> whereLambda,
28
29                                           bool isAsc, Expression<Func<T, S>> orderByLambda);

  (4)上面我们简单的介绍了一下Func<T, bool>和Expression<Func<T, bool>>的使用区别,我查到了就这些资料,如果那位博友还能够详细的说明的话,真心希望你在下面留言,我将非常的感谢你们。我参考的资料是:http://www.cnblogs.com/dudu/archive/2012/04/01/enitity_framework_func.html

  (5)综上所述的话,这时候我们就要对我们项目中数据库访问层,数据库访问接口层,业务逻辑层和业务逻辑接口层的查询方法都进行修改,这里就不多说了,和上面的基本差不多。

2.登录页面的设计

  (1)首先我们到网上下载一个登录页面的Demo,然后经过修改之后放到我们MVC4的项目里面。

  (2)然后我们在项目中添加一个LoginController控制器,然后再在Index上面添加一个空视图,最后我们将我们前面下载的Demo中的代码部署到Index.cshtml页面之上,最后生成的静态页面如图所示:

   

  (3)这时候我们就把静态页面设计好了,这里静态页面的代码我就不往出来贴了,在后面我会把主要的代码写出来的并且共享整个项目的,那么下来我们看到了我们的验证码没有实现,只是一个假的图标在哪里,这时候我们开始着手验证码的设计。

3.如何设计验证码的实现

  (1)通过上图我们看到现在我们已经实现了页面的展示,那么我们的验证码还没有,现在开始我们设计验证码,首先看我前台验证码这里的代码是:

 1 <ul>
 2
 3    <li class="user_main_text">验证码: </li>
 4
 5    <li class="user_main_input">
 6
 7        <input type="text" class="TxtPasswordCssClass" id="Code" name="Code">
 8
 9    </li>
10
11 </ul>
12
13 <ul>
14
15    <li class="user_main_text">验证码: </li>
16
17    <li class="user_main_input">
18
19 <img src="/Login/CheckCode?ID=1" id="imgCode" alt="单击可刷新" onclick="ClickRemoveChangeCode()"  />
20
21 <a href="javascript:void(0)" onclick="ClickRemoveChangeCode();return false;">看不清</a>
22
23     </li>
24
25 </ul>

  (2)首先我们看到我们绑定验证码的这里是这样写的,<img src=”/Login/CheckCode?ID=1”>,那么前面的src绑定的地址什么意思呢?他的意思就是我们在Login控制器下面含有一个CheckCode方法来实现验证码的读取。

  (3)我们要实现验证码,首先我们就要写一个生成验证码的类,没什么难度,网上一搜一大推,下面就是我封装的生成验证码的类,首先我们在LYZJ.UserLimitMVC.Common类库下面新建一个KenceryValidateCode.cs类来存放生成验证码的代码,在这里我们需要给类库引入命名空间System.Drawing。最终的代码如下:

  1 namespace LYZJ.UserLimitMVC.Common
  2
  3 {
  4
  5     public class KenceryValidateCode
  6
  7     {
  8
  9         /// <summary>
 10
 11         /// 验证码的最大长度
 12
 13         /// </summary>
 14
 15         public int MaxLength
 16
 17         {
 18
 19             get { return 10; }
 20
 21         }
 22
 23
 24
 25         /// <summary>
 26
 27         /// 验证码的最小长度
 28
 29         /// </summary>
 30
 31         public int MinLength
 32
 33         {
 34
 35             get { return 1; }
 36
 37         }
 38
 39
 40
 41         /// <summary>
 42
 43         /// 生成验证码
 44
 45         /// </summary>
 46
 47         /// <param name="length">指定验证码的长度</param>
 48
 49         /// <returns></returns>
 50
 51         public string CreateValidateCode(int length)
 52
 53         {
 54
 55             int[] randMembers = new int[length];
 56
 57             int[] validateNums = new int[length];
 58
 59             string validateNumberStr = "";
 60
 61             //生成起始序列值
 62
 63             int seekSeek = unchecked((int) DateTime.Now.Ticks);
 64
 65             Random seekRand = new Random(seekSeek);
 66
 67             int beginSeek = (int) seekRand.Next(0, Int32.MaxValue - length*10000);
 68
 69             int[] seeks = new int[length];
 70
 71             for (int i = 0; i < length; i++)
 72
 73             {
 74
 75                 beginSeek += 10000;
 76
 77                 seeks[i] = beginSeek;
 78
 79             }
 80
 81             //生成随机数字
 82
 83             for (int i = 0; i < length; i++)
 84
 85             {
 86
 87                 Random rand = new Random(seeks[i]);
 88
 89                 int pownum = 1*(int) Math.Pow(10, length);
 90
 91                 randMembers[i] = rand.Next(pownum, Int32.MaxValue);
 92
 93             }
 94
 95             //抽取随机数字
 96
 97             for (int i = 0; i < length; i++)
 98
 99             {
100
101                 string numStr = randMembers[i].ToString();
102
103                 int numLength = numStr.Length;
104
105                 Random rand = new Random();
106
107                 int numPosition = rand.Next(0, numLength - 1);
108
109                 validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
110
111             }
112
113             //生成验证码
114
115             for (int i = 0; i < length; i++)
116
117             {
118
119                 validateNumberStr += validateNums[i].ToString();
120
121             }
122
123             return validateNumberStr;
124
125         }
126
127
128
129         //C# MVC 升级版
130
131         /// <summary>
132
133         /// 创建验证码的图片
134
135         /// </summary>
136
137         /// <param name="containsPage">要输出到的page对象</param>
138
139         /// <param name="validateNum">验证码</param>
140
141         public byte[] CreateValidateGraphic(string validateCode)
142
143         {
144
145             Bitmap image = new Bitmap((int) Math.Ceiling(validateCode.Length*12.0), 22);
146
147             Graphics g = Graphics.FromImage(image);
148
149             try
150
151             {
152
153                 //生成随机生成器
154
155                 Random random = new Random();
156
157                 //清空图片背景色
158
159                 g.Clear(Color.White);
160
161                 //画图片的干扰线
162
163                 for (int i = 0; i < 25; i++)
164
165                 {
166
167                     int x1 = random.Next(image.Width);
168
169                     int x2 = random.Next(image.Width);
170
171                     int y1 = random.Next(image.Height);
172
173                     int y2 = random.Next(image.Height);
174
175                     g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
176
177                 }
178
179                 Font font = new Font("Arial", 12, (FontStyle.Bold | FontStyle.Italic));
180
181                 LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),
182
183                                                                     Color.Blue, Color.DarkRed, 1.2f, true);
184
185                 g.DrawString(validateCode, font, brush, 3, 2);
186
187                 //画图片的前景干扰点
188
189                 for (int i = 0; i < 100; i++)
190
191                 {
192
193                     int x = random.Next(image.Width);
194
195                     int y = random.Next(image.Height);
196
197                     image.SetPixel(x, y, Color.FromArgb(random.Next()));
198
199                 }
200
201                 //画图片的边框线
202
203                 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
204
205                 //保存图片数据
206
207                 MemoryStream stream = new MemoryStream();
208
209                 image.Save(stream, ImageFormat.Jpeg);
210
211                 //输出图片流
212
213                 return stream.ToArray();
214
215             }
216
217             finally
218
219             {
220
221                 g.Dispose();
222
223                 image.Dispose();
224
225             }
226
227         }
228
229
230
231         /// <summary>
232
233         /// 得到验证码图片的长度
234
235         /// </summary>
236
237         /// <param name="validateNumLength">验证码的长度</param>
238
239         /// <returns></returns>
240
241         public static int GetImageWidth(int validateNumLength)
242
243         {
244
245             return (int) (validateNumLength*12.0);
246
247         }
248
249
250
251         /// <summary>
252
253         /// 得到验证码的高度
254
255         /// </summary>
256
257         /// <returns></returns>
258
259         public static double GetImageHeight()
260
261         {
262
263             return 22.5;
264
265         }
266
267     }
268
269 }

  (4)那么现在我们的验证码生成的类已经完成了,这时候我们根据<img src=”/Login/CheckCode?ID=1”>所知,我们要到Login控制器下面去创建CheckCode方法来实现能够从View层读取验证码显示出来,那么必然在我们项目当中women就要用到刚才定义的获取验证码的类,那么这时候women就要添加LYZJ.UserLimitMVC.Common的引用,这时候在Login控制器下面的读取验证码的方法代码如下:

 1        /// <summary>
 2
 3         /// 验证码的实现
 4
 5         /// </summary>
 6
 7         /// <returns></returns>
 8
 9         public ActionResult CheckCode()
10
11         {
12
13             //首先实例化验证码的类
14
15             KenceryValidateCode validateCode = new KenceryValidateCode();
16
17             //生成验证码指定的长度
18
19             string code = validateCode.CreateValidateCode(5);
20
21             //将验证码赋值给Session变量
22
23             Session["ValidateCode"] = code;
24
25             //创建验证码的图片
26
27             byte[] bytes = validateCode.CreateValidateGraphic(code);
28
29             //最后将验证码返回
30
31             return File(bytes, @"image/jpeg");
32
33         }

  (5)根据上面的代码,我们就实现了能够在前台显示验证码的功能,这里我就不详细的解释代码了,我在代码里面写了大量的注释,相信大家能够很容易的明白代码的意思,效果如图所示:

         

  (6)那么这时候我们就有一个问题出现了,我们的验证码有时候可能看不清,当我们要单击”验证码本身”或者”看不清,换一张”的时候要能够动态的变化,下面我就简单介绍一下动态的变化验证码。

4.单击验证码的时候验证码随机获取

  (1)当我们想要单击”验证码本身”或者”看不清,换一张”的字眼的时候我们就要实施的刷新一下验证码,那么我们看到我们在页面的HTML代码中就有一个javaScript的Clieck事件,<img src="/Login/CheckCode?ID=1" id="imgCode" alt="单击可刷新" onclick="ClickRemoveChangeCode()"  /> ,最后我们只要使用JavaScript实现onClick事件的ClickRemoveChangeCode()方法,使用JavaScript实现此事件的方法如下:

 1      @*引用Jquery文件的JS脚本*@
 2
 3         <script src="~/Scripts/jquery-1.7.1.min.js"></script>
 4
 5         <script type="text/javascript">
 6
 7             //单击重新改变验证码
 8
 9             function ClickRemoveChangeCode() {
10
11                 //首先我们获取到验证码的路径
12
13                 var code = $("#imgCode").attr("src");
14
15                 //然后重新给验证码的路径赋值
16
17                 $("#imgCode").attr("src", code + "1");
18
19             }
20
21         </script>

  (2)这样我们的验证码就实现了,当然还有一些小样式的修改我就不说了,比如当鼠标移动上去的时候能够变成小手等。

  (3)那么下篇博客我们将实现用户的登录,越往后面的话我会越说的简单,这些东西都不怎么难,如果大家不太清楚的话,可以留言或者加QQ群,我将很高兴为我们解决问题。

  (4)最后在秀一下今天完成的验证码的功能,本来打算把登录一起写的,可是就验证码写了这么多,想想还是把登录放后面和写T4模版一起说吧。

     

  

  Kencery返回本系列开篇

  

时间: 2024-11-18 19:17:22

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改的相关文章

ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开篇

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开篇 前言:博客又有一段时间没有更新了,心里感觉这段时间空空的,好像什么都没有学下,所以就想写博客,所以就有了这个系列,这里当然也要感谢大家了,因这个项目我已经上传了,得到了很多网友的评价,也有好多人发邮件给我说这个框架容易出现问题,不能访问,这也是支持我写这个系列的动力,我将这个项目写成一个系列,可能要很长时间吧,但是我肯定会一直坚持,如果我哪里写的不好欢迎大家指出我们共同学习,而且我理解的也不是很透彻,所以我想在写这样一遍

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(16)-类库架构扩展以及DLL文件生成修改和用户的简单添加

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(16)-类库架构扩展以及DLL文件生成修改和用户的简单添加 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    (5):前台Jquery easyUI实现    (6):EF上下文实例管理    (7):DBSession的封装   (8):DBSession线程内唯一     

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(23)-设置角色遗留问题和为权限设置角色以及EasyUI Tabs的使用

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(23)-设置角色遗留问题和为权限设置角色以及EasyUI Tabs的使用 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装          (5):前台Jquery easyUI实现   (6):EF上下文实例管理    (7):DBSession的封装   (8):DBSessi

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(13)-权限设计

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(13)-权限设计 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    (5):前台Jquery easyUI实现    (6):EF上下文实例管理    (7):DBSession的封装   (8):DBSession线程内唯一     (9):TT摸版的学习    (10):V

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    (5):前台Jquery easyUI实现    (6):EF上下文实例管理    (7):DBSession的封装   (8):DBSession线程内唯一     (9):TT摸版的学习    (1

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(8)-DbSession线程内唯一

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(8)-DbSession线程内唯一 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装  (5):前台Jquery easyUI实现   (6):EF上下文实例管理   (7):DBSession的封装 前言:通过上篇博客我们完成了对DbSession的代码编写,DbSession就相

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(5)-前台JqueryEasyUI前台实现

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(5)-前台JqueryEasyUI前台实现 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装 前言:今天经理买了一个诺基亚的Windows Phone 8系统,特感兴趣,所以在哪里看了很长时间,这篇文章就写的有点迟, 从这个Demo开始到现在我已经写了4篇博客了,终于可以看到页面的东

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(22)-为用户设置角色

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(22)-为用户设置角色 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装          (5):前台Jquery easyUI实现   (6):EF上下文实例管理    (7):DBSession的封装   (8):DBSession线程内唯一          (9):TT摸版

ASP.NET MVC+EF框架+EasyUI实现权限管理系列(4)-业务逻辑层的封装

原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(4)-业务逻辑层的封装 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程 前言:前面几篇博客我们基本已经介绍完了搭建整个项目和数据库访问层以及一些业务逻辑层的实现,当然了,我们的数据库访问层这样还是可以在进行封装的,但是我到这里就行了吧,项目也不大,不需要那么麻烦的,那么我们今天开始介绍我们需要介绍的内容,那就是我