mvc示例项目之二----登录功能实现

写在前面的

本节用登录功能介绍一个Controller及View层的编写。.net的mvc框架将每个可调用函数是Controller当中的一个返回值为ActionResult函数。ActionResult是一个父类,一般来说最常用的返回值为ViewResult、JsonResult、FileResult。ViewResult返回一个页面,JsonResult返回一个Json对象(一般用于ajax调用),FileResult返回一个文件(图片等)。

图一、ActionResult类继承关系

本博客系列通过两个Controller及有限的几个View页面将这三个ActionResult返回类型都进行介绍。

由于侧重于介绍mvc,所以Ajax、Json等基本概念就不做赘述,不了解这些概念的朋友们可以百度或者必应。

首先,将对bs系统的大门——登录页面进行介绍。

登录功能简介

登录功能是一个bs系统的门户,本节介绍如何生成认证码图片、如何验证跳转。下一节介绍如何使用Filter权限认证。

登录实现

Mvc3.0采用了Razor模板,可以说写前端代码很是明晰舒服。如下是View页面代码。

 

@model Entity.Admin
@{
    Layout = null;
}
<html>
<head>
    <title>登陆网站</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <style type="text/css">
        INPUT
        {
            border-right: #000000 1px solid;
            border-top: #000000 1px solid;
            border-left: #000000 1px solid;
            border-bottom: #000000 1px solid;
            height: 20px;
        }
        TD
        {
            font-size: 12px;
        }
        .inll
        {
            border-right: #ffffff;
            border-top: #ffffff;
            border-left: #ffffff;
            border-bottom: #ffffff;
        }
        .STYLE1
        {
            color: #FFFFFF;
        }
        .STYLE3
        {
            color: #FFFFFF;
            font-weight: bold;
        }
    </style>
    <script src="@Url.Content("~/Scripts/jquery-1.7.2.min.js")" type="text/javascript"></script>
    <script type="text/javascript">
    function CheckForm() {
        if (document.Login.UserName.value == "") {
            alert("请输入用户名!");
            document.Login.UserName.focus();
            return false;
        }
        if (document.Login.Password.value == "") {
            alert("请输入密码!");
            document.Login.Password.focus();
            return false;
        }
        if (document.Login.CheckCode.value == "") {
            alert("请输入您的验证码!");
            document.Login.CheckCode.focus();
            return (false);
        }
        return true;
    }

    function Check() {
        if(!CheckForm()){
           return false;
        }
           $.post("@Url.Action("Loginin")", { UserName: $("#UserName").val(),Password:$("#Password").val(), CheckCode:$("#CheckCode").val()},function(data){
                                              
                                              if(data.flag){//如果验证成功,则跳转
                                                window.location.href=data.msg;
                                              }
                                              else{
                                                alert(data.msg);//弹出失败信息
                                              }
                                              
                                           });
    }
      function RefreshImage()
        {
            var el =document.getElementById("codeImg");
            el.src=el.src+'?';//这个特别重要
        }
    </script>
</head>
<body bgcolor="#FFFFFF" background="" leftmargin="0" topmargin="0" marginwidth="0"
    marginheight="0">
    <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0">
        <tr>
            <td height="308" valign="middle">
                <table cellspacing="0" cellpadding="0" width="100%" align="center" bgcolor="#ffffff"
                    border="0">
                    <tbody>
                        <tr>
                            <td height="182" align="center" valign="bottom">
                            </td>
                        </tr>
                        <tr>
                            <td height="8" valign="bottom">
                            </td>
                        </tr>
                        <tr>
                            <TD height="160" align="center" valign="bottom" background="@Url.Content("~/Content/images/line.gif")">
                                <table width="59%" align="center" border="0">
                                    <tbody>
                                        <tr>
                                            <td width="32%" height="183" align="center" valign="middle">
                                                <img src="@Url.Content("~/Content/images/Login_pic.gif")" width="130" height="106">
                                            </td>
                                            <td width="3%" valign="top">
                                                <img src="@Url.Content("~/Content/images/Login_line.gif")" width="2" height="150">
                                            </td>
                                            <td width="65%">
                                                <form name="Login" method="post" target="_parent">
                                                <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0">
                                                    <tbody>
                                                        <tr>
                                                            <td height="26" colspan="2" nowrap>
                                                                <img src="@Url.Content("~/Content/images/Login_tit.gif")" width="370" height="42">
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <td width="31%" height="26" align="right" nowrap>
                                                                <span class="STYLE3">用户名:</span>
                                                            </td>
                                                            <td width="69%" height="26" nowrap>
                                                                <input name="UserName" type="text" id="UserName" maxlength="20" style="width: 160px;
                                                                    border-style: solid; border-width: 1; padding-left: 4; padding-right: 4; padding-top: 1;
                                                                    padding-bottom: 1" onmouseover="this.style.background='#E1F4EE';" onmouseout="this.style.background='#FFFFFF'"
                                                                    onfocus="this.select(); ">
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <td height="26" align="right" nowrap class="STYLE3">
                                                                密 码:
                                                            </td>
                                                            <td nowrap height="26">
                                                                <input name="Password" id="Password" type="Password" maxlength="20" style="width: 160px;
                                                                    border-style: solid; border-width: 1; padding-left: 4; padding-right: 4; padding-top: 1;
                                                                    padding-bottom: 1" onmouseover="this.style.background='#E1F4EE';" onmouseout="this.style.background='#FFFFFF'"
                                                                    onfocus="this.select(); ">
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <td height="26" align="right" nowrap class="STYLE3">
                                                                验证码:
                                                            </td>
                                                            <td nowrap height="26">
                                                                <input name="CheckCode" id="CheckCode" size="6" maxlength="4" style="border-style: solid;
                                                                    border-width: 1; padding-left: 4; padding-right: 4; padding-top: 1; padding-bottom: 1"
                                                                    onmouseover="this.style.background='#E1F4EE';" onmouseout="this.style.background='#FFFFFF'"
                                                                    onfocus="this.select(); ">
                                                                <img src="@Url.Action("GetValidateCode")" id="codeImg" onclick="RefreshImage()" alt="点击重刷新" />
                                                            </td>
                                                        </tr>
                                                        <tr>
                                                            <td height="26" colspan="2" align="center">
                                                                <input type="button" name="Submit" onclick="Check();" value=" 确 认 " style="font-size: 9pt;
                                                                    height: 19; width: 60; color: #000000; background-color: #E1F4EE; border: 1 solid #E1F4EE"
                                                                    onmouseover="this.style.backgroundColor='#ffffff'" onmouseout="this.style.backgroundColor='#E1F4EE'">
                                                                 
                                                                <input name="reset" type="reset" id="reset" value=" 清 除 " style="font-size: 9pt;
                                                                    height: 19; width: 60; color: #000000; background-color: #E1F4EE; border: 1 solid #E1F4EE"
                                                                    onmouseover="this.style.backgroundColor='#ffffff'" onmouseout="this.style.backgroundColor='#E1F4EE'">
                                                            </td>
                                                        </tr>
                                                    </tbody>
                                                </table>
                                                </form>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
        <tr>
            <td height="20" align="center">
                 
            </td>
        </tr>
    </table>
</body>
</html>

 

 

 

 


接收用户登录请求的函数叫做Login(),位于Home控制器下。代码如下:

 

        public ActionResult Login()
        {

            return View();
        }

细心的读者会发现,只有一句。是的,只返回一个ViewResult,然后请求页面即展现出来。

 

由于采用Ajax提交,所以提交按钮采用Button事件,如果采用Submit控件需要重写Onsubmit方法。由于前端用Jquery实现Ajax提交,所以代码不是很繁琐。以下是Jquery ajax提交方式:

 $.post("@Url.Action("Loginin")", { UserName: $("#UserName").val(),Password:$("#Password").val(), CheckCode:$("#CheckCode").val()},function(data){
                                              
                                              if(data.flag){//验证成功跳转
                                                window.location.href=data.msg;
                                              }
                                              else{
                                                alert(data.msg);//弹出失败信息
                                              }
                                              
                                           });

上述代码发送请求及返回请求都是Json字符串。由于两个方法位于同一个控制器下,所以在view页面中填写地址时只需要填写Url.Action(“actionname”)即可。如果不在同一个控制器下,则需要填写Url.Action(“ActionName”,”ControllerName”)方可。后台的验证代码如下:

 


     public ActionResult Loginin(Admin admin, string CheckCode)
        {
            object sessionCodeObj= Session["ValidateCode"];//获取验证码
            string sessionCode=(sessionCodeObj==null?string.Empty:sessionCodeObj.ToString());
            if (!CheckCode.Equals(sessionCode))//如果验证码输入错误
            {
                return Json(new { flag = false, msg = "验证码输入错误!" }, JsonRequestBehavior.AllowGet);
            }
            Admin old = EntityDMHelper.GetAdminByName(admin.UserName);//通过用户名获取用户实体
            if (old == null)
            {
                return Json(new { flag = false, msg = "不存在该用户!" }, JsonRequestBehavior.AllowGet);
            }
            if (!VerifyMD5(admin.Password, old.Password))//验证用户密码
            {
                return Json(new { flag = false, msg = "密码错误!" }, JsonRequestBehavior.AllowGet);
            }
            FormsAuthentication.SetAuthCookie(admin.UserName, false);//添加认证信息
            return Json(new { flag = true, msg = Url.Action("GetList", "Article") }, JsonRequestBehavior.AllowGet);
        }
        private  string MD5(string str)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToString();

        }

        private  bool VerifyMD5(string str, string md5str)
        {
            return MD5(str).Equals(md5str);
        } 

 

上述代码返回的是JsonResult。可以比照参数,看看前后台如何交互。那么验证码生成的代码又是如何呢?

验证码的生成

 

        public ActionResult GetValidateCode()
        {
            ValidateCode vCode = new ValidateCode();
            string code = vCode.CreateValidateCode(4);
            Session["ValidateCode"] = code;//插入session
            byte[] bytes = vCode.CreateValidateGraphic(code);//生成图片
            return File(bytes, @"image/jpeg");
        }


在验证码生成时,将验证码字符串插入到session中,同时返回一个img文件。那么前端如何接收呢?

 

 

        function RefreshImage()//刷新验证码
        {
            var el =document.getElementById("codeImg");
            el.src=el.src+'?';//这个特别重要
        }
<img src="@Url.Action("GetValidateCode")" id="codeImg" onclick="RefreshImage()" alt="点击重刷新" />

当点击图片时,可以刷新图片,防止session过期。

 

验证码图片类

下面是验证码图片类:

 

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web.UI;
using System.Drawing.Drawing2D;
using System.IO;

namespace HaiLiang.Common
{
    /// <summary>
    /// 生成验证码的类
    /// </summary>
    public class ValidateCode
    {
        public ValidateCode()
        {
        }
        /// <summary>
        /// 验证码的最大长度
        /// </summary>
        public int MaxLength
        {
            get { return 10; }
        }
        /// <summary>
        /// 验证码的最小长度
        /// </summary>
        public int MinLength
        {
            get { return 1; }
        }
        /// <summary>
        /// 生成验证码
        /// </summary>
        /// <param name="length">指定验证码的长度</param>
        /// <returns></returns>
        public string CreateValidateCode(int length)
        {
            int[] randMembers = new int[length];
            int[] validateNums = new int[length];
            string validateNumberStr = "";
            //生成起始序列值
            int seekSeek = unchecked((int)DateTime.Now.Ticks);
            Random seekRand = new Random(seekSeek);
            int beginSeek = (int)seekRand.Next(0, Int32.MaxValue - length * 10000);
            int[] seeks = new int[length];
            for (int i = 0; i < length; i++)
            {
                beginSeek += 10000;
                seeks[i] = beginSeek;
            }
            //生成随机数字
            for (int i = 0; i < length; i++)
            {
                Random rand = new Random(seeks[i]);
                int pownum = 1 * (int)Math.Pow(10, length);
                randMembers[i] = rand.Next(pownum, Int32.MaxValue);
            }
            //抽取随机数字
            for (int i = 0; i < length; i++)
            {
                string numStr = randMembers[i].ToString();
                int numLength = numStr.Length;
                Random rand = new Random();
                int numPosition = rand.Next(0, numLength - 1);
                validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
            }
            //生成验证码
            for (int i = 0; i < length; i++)
            {
                validateNumberStr += validateNums[i].ToString();
            }
            return validateNumberStr;
        }
        /// <summary>
        /// 创建验证码的图片
        /// </summary>
        /// <param name="containsPage">要输出到的page对象</param>
        /// <param name="validateNum">验证码</param>
        public byte[] CreateValidateGraphic(string validateCode)
        {
            Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), 22);
            Graphics g = Graphics.FromImage(image);
            try
            {
                //生成随机生成器
                Random random = new Random();
                //清空图片背景色
                g.Clear(Color.White);
                //画图片的干扰线
                for (int i = 0; i < 25; i++)
                {
                    int x1 = random.Next(image.Width);
                    int x2 = random.Next(image.Width);
                    int y1 = random.Next(image.Height);
                    int y2 = random.Next(image.Height);
                    g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
                }
                Font font = new Font("Arial", 12, (FontStyle.Bold | FontStyle.Italic));
                LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),
                 Color.Blue, Color.DarkRed, 1.2f, true);
                g.DrawString(validateCode, font, brush, 3, 2);
                //画图片的前景干扰点
                for (int i = 0; i < 100; i++)
                {
                    int x = random.Next(image.Width);
                    int y = random.Next(image.Height);
                    image.SetPixel(x, y, Color.FromArgb(random.Next()));
                }
                //画图片的边框线
                g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
                //保存图片数据
                MemoryStream stream = new MemoryStream();
                image.Save(stream, ImageFormat.Jpeg);
                //输出图片流
                return stream.ToArray();
            }
            finally
            {
                g.Dispose();
                image.Dispose();
            }
        }
        /// <summary>
        /// 得到验证码图片的长度
        /// </summary>
        /// <param name="validateNumLength">验证码的长度</param>
        /// <returns></returns>
        public static int GetImageWidth(int validateNumLength)
        {
            return (int)(validateNumLength * 12.0);
        }
        /// <summary>
        /// 得到验证码的高度
        /// </summary>
        /// <returns></returns>
        public static double GetImageHeight()
        {
            return 22.5;
        }
    }
}

 


说实话验证码是从网上找到的。让我们感谢原创者及不断的复制者们。

 

图二、登录页面局部

图三、登录后页面

 

如此,就简单的实现了登录功能。可以看出代码的优雅。

好了,本节至此结束。下节我们看看如何用Filter简单验证登录身份。

posted @ 2013-09-22 19:39  明义经典  阅读(603)  评论(0)    收藏  举报