环境搭好了,开始编码。第一步当然是写登录。说明一下,因为是练习,我没有事先做比较全面的规划(数据库等),各种表都是写到该功能再加上。
功能:表单验证,密码验证码验证,点击换验证码
效果图:
难点:(本人在编码过程中遇到的问题记录)
①、登录表单居中显示 —— 用VBox布局可以保证水平居中,然后用margin控制上边距
②、ExtJS怎么放图片(验证码)——用Componet(box),用autoEl配置
③、ExtJS点击切换验证码——Componet本身没有click事件,用用getEl方法获得图片element,然后绑定click事件,重新赋予src属性,注意后面要加时间参数避免get缓存
【一】新建用户表 - SYS_FW_USER
用的PowerDesigner连接Oracle,建模后直接生成(方法见本人另一篇博客)——主要是为了学习和熟悉下这个建模工具,其实没必要的,呵呵。
先就id和password这俩必填字段,先把登录做了,其他的以后再加,新建一个用户admin/admin(md5加密)测试用。
【二】前台(ExtJS画界面)
用Extjs实现一些表单验证很方便,用labelWidth,Margin配置实现一些对齐。
1 <!DOCTYPE html> 2 3 <html> 4 <head> 5 <meta name="viewport" content="width=device-width" /> 6 <title>Index</title> 7 <script src="../../Scripts/jquery-1.7.1.js" type="text/javascript"></script> 8 <script src="../../Scripts/ExtJS/ext-all.js" type="text/javascript"></script> 9 <link href="../../Scripts/ExtJS/resources/ext-theme-neptune/ext-theme-neptune-all.css" 10 rel="stylesheet" type="text/css" /> 11 <script src="../../Scripts/ExtJS/locale/ext-lang-zh_CN.js" type="text/javascript"></script> 12 <script src="../../Scripts/ExtJS/examples.js" type="text/javascript"></script> 13 <link href="../../Scripts/ExtJS/example.css" rel="stylesheet" type="text/css" /> 14 <style> 15 .viewPort 16 { 17 background-image:url("../../Resources/bg/5-1206010S327-51.gif"); 18 } 19 </style> 20 <script type="text/javascript"> 21 Ext.onReady(function () { 22 //视图区域 23 var viewPort = Ext.create('Ext.container.Viewport', { 24 cls: "viewPort", 25 layout: { 26 type: "vbox", 27 align: 'center' 28 } 29 }); 30 31 //登录表单 32 var form_login = Ext.create("Ext.form.Panel", { 33 title: "登录", 34 id: "form_login", 35 width: 400, 36 height: 200, 37 margin: "200 0 0 0", 38 items: [ 39 { 40 xtype: "textfield", 41 fieldLabel: "用户名", 42 id: "text_id", 43 labelWidth: 130, 44 labelAlign: "right", 45 maxLength: 10, 46 enforceMaxLength: true, 47 margin: "20 20 10 10", 48 allowBlank: false, 49 blankText: "请输入用户名" 50 }, 51 { 52 xtype: "textfield", 53 inputType: "password", 54 id: "text_password", 55 fieldLabel: "密码", 56 labelWidth: 130, 57 labelAlign: "right", 58 margin: "0 20 10 10", 59 allowBlank: false, 60 blankText: "请输入密码" 61 }, 62 { 63 xtype: "container", 64 layout: "column", 65 items: [ 66 { 67 xtype: "textfield", 68 id:"text_yzm", 69 width: 210, 70 maxLength: 5, 71 enforceMaxLength: true, 72 fieldLabel: "验证码", 73 labelWidth: 130, 74 allowBlank: false, 75 blankText: "请输入验证码", 76 labelAlign: "right", 77 margin: "0 10 10 10" 78 }, 79 { 80 xtype: 'box', //或者xtype: 'component', 81 id: "box_yzm", 82 width: 63, //图片宽度 83 height: 22, //图片高度 84 autoEl: { 85 tag: 'img', //指定为img标签 86 src: 'Home/Yzm' 87 }, 88 listeners: { 89 render: function (c) { 90 c.getEl().on({ 91 click: function () { 92 c.getEl().dom.src = 'Home/Yzm/'+ '?dc=' + new Date().getTime(); 93 } 94 }); 95 } 96 } 97 }, 98 { 99 xtype: "panel", 100 border: false, 101 margin: "5 0 0 20", 102 html: "<a href='javascript:changeYzm()'>看不清?</a>" 103 } 104 ] 105 } 106 ], 107 buttons: [ 108 { text: "确定", handler: Login }, 109 { text: "取消", handler: function () { form_login.form.reset() } } 110 ] 111 }); 112 113 //将表单添加到视图区域 114 viewPort.add(form_login); 115 }); 116 117 function Login() { 118 119 if(!Ext.getCmp("form_login").isValid()) 120 { 121 return false; 122 } 123 124 var id = Ext.getCmp("text_id").getValue(); 125 var password = Ext.getCmp("text_password").getValue(); 126 var yzm = Ext.getCmp("text_yzm").getValue(); 127 Ext.Ajax.request({ 128 url: "Home/Login/", 129 params: { id: id, password: password, yzm: yzm }, 130 success: function (response) { 131 if (response.responseText == "ok") { 132 Ext.example.msg("登录", "登录成功", "success"); 133 } 134 else if(response.responseText == "yzmError") 135 { 136 Ext.example.msg("登录", "登录失败,验证码错误", "error"); 137 } 138 else { 139 Ext.example.msg("登录", "登录失败,用户名或密码不正确", "error"); 140 } 141 } 142 }); 143 } 144 145 function changeYzm() 146 { 147 Ext.getCmp("box_yzm").getEl().dom.src = 'Home/Yzm/' + '?dc=' + new Date().getTime(); 148 } 149 </script> 150 </head> 151 <body> 152 <div> 153 154 </div> 155 </body> 156 </html>
【三】后台(HomeController各个action处理登录验证及验证码)
后台用苏飞类库里的YzmHelper可以很方便生成验证码,生成把验证吧文本放到session里面,登录时验证就行了。用实体框架访问数据库很方便。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MyFramework.Models.FW;
using DotNet.Utilities;
using System.Drawing;
using System.IO;
namespace MyFramework.Controllers
{
public class HomeController : Controller
{
//
// GET: /Login/
public ActionResult Index()
{
return View();
}
public string Login(User user)
{
string yzm = Request["yzm"];
if (string.IsNullOrEmpty(yzm) || yzm != Session["yzm"].ToString())
{
return "yzmError";
}
if (user.id != null)
{
Entities context = new Entities();
string md5Pwd = Encrypt.Md5(user.password);
var match = context.SYS_FW_USER.SingleOrDefault(u => u.ID == user.id && u.PASSWORD == md5Pwd);
if (match != null)
{
return "ok";
}
}
return "error";
}
public ActionResult Yzm()
{
YZMHelper yzm = new YZMHelper();
Bitmap bmp = yzm.Image;
Session["yzm"] = yzm.Text;
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
return File(ms.ToArray(), "image/jpeg");
}
}
}