MVC 用户登陆(验证码)

本文介绍了一个基于ASP.NET MVC4的登录验证系统实现,包括前后端交互、验证码生成及验证过程。系统通过分离关注点的方式组织代码,分为UI、BLL、DAL等层次。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建解决方案 Itcast.CMS

创建:Itcast.CMS.BLL类库

创建:Itcast.CMS.DAL类库

创建:Itcast.CMS.Model类库

创建:Itcast.CMS.Common类库 (阔们:工具类库,我们常用的工具类,就放到这里面)

创建:Itcast.CMS.WebApp  (  ASP.NET MVC4应用程序)



Login 控制器  (UI层 调用BLL层的方法)

using Itcast.CMS.BLL;
using Itcast.CMS.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Itcast.CMS.WebApp.Controllers
{
    public class LoginController : Controller
    {
        /// <summary>
        /// 登陆页面
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 登陆成功后,跳转到此页面
        /// </summary>
        /// <returns></returns>
        public ActionResult Login()
        {
            return View();
        }

        /// <summary>
        /// 检测用户输入的用户名(Email),密码,验证码是否正确
        /// </summary>
        /// <returns>错误的文字信息</returns>
        public ActionResult UserLogin()
        {
            string vCode = Session["vCode"] == null ? string.Empty : Session["vCode"].ToString();
            if (string.IsNullOrWhiteSpace(vCode))
            {
                return Content("no:没有输入验证码");
            }
            Session["vCode"] = null;//因为前面已经给这个Session["vCode"]赋值给vCode了。所以此时系统里存的这个Session["vCode"]就没有用了,我们将它清空(需要的时候我们只要使用vCode就行了)
            string txtCode = Request["VCoe"];
            if (!txtCode.Equals(vCode, StringComparison.InvariantCultureIgnoreCase)) //如果验证码有字母,就忽略字母的大小写进行对比
            {
                return Content("no:验证码不正确");
            }

            string userName = Request["UserName"];
            string userMail=Request["UserName"]; //同时可以使用Email来登陆
            string userPwd = Request["UserPwd"];
            BLL.UserInfoService userService = new UserInfoService();
            UserInfo user = userService.GetUserInfo(userName, userPwd, userMail); //调用BLL层中的方法
            if (user != null)
            {
                Session["userInfo"] = user;
                return Content("ok:登陆成功");
            }
            else
            {
                return Content("no:登陆失败");
            }

        }
        /// <summary>
        /// 调用Itcast.CMS.Common类库中的ValidateCode类 来显示验证码
        /// </summary>
        /// <param name="str">无用处的参数</param>
        /// <returns>图片文件</returns>
        public ActionResult ShowValiDataCode(string str)
        {
            Itcast.CMS.Common.ValidateCode vcode = new Common.ValidateCode();
            string code= vcode.CreateValidateCode(5);
            Session["vCode"] = code;
            return File(vcode.CreateValidateGraphic(code), "image/JPEG");
        }

    }
}

Index视图

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <script src="~/Scripts/jquery-1.8.2.js"></script>
    <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
    <script src="~/Content/ie-emulation-modes-warning.js"></script>
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
    <link href="~/Content/signin.css" rel="stylesheet" />
    <style type="text/css">
        #inputVcode {
            width: 80px;
        }

        #inputVcode, img {
            float: left;
        }

        .clear {
            clear: both; /*-------清除浮动-----------*/
        }
    </style>
</head>
<body>
    <div class="container">
        @*OnSuccess = "afterLogin"表示:如果请求成功,就调用afterLogin函数(其实就是jquery中的 success:function afterLogin(){})*@
        @*id = "form-signin" class = "form-signin" 是设置当前form表单的id和class"为form-signin"*@ 
        @using (Ajax.BeginForm("UserLogin", new { }, new AjaxOptions { HttpMethod = "post", OnSuccess = "afterLogin" }, new { id = "form-signin", @class = "form-signin" }))
        {
            
            <h2 class="form-signin-heading">请登录</h2>
            <label for="inputEmail" class="sr-only">Email 地址</label>
            <input type="email" id="inputEmail" class="form-control" name="UserName" placeholder="Email 地址" required autofocus>
            <label for="inputPassword" class="sr-only">密码</label>
            <input type="password" id="inputPassword" class="form-control" name="UserPwd" placeholder="密码" required>
            <div><input type="text" id="inputVcode" class="form-control" name="VCoe" placeholder="验证码" required><img src="Login/ShowValiDataCode/?id=1; style="height:30px;width:70px;" id="ImageCode" class="validataCode" /><a href="#" class="validataCode">看不清,换一张</a></div>
            <div class="clear"></div>  @*清除浮动*@
            <div class="checkbox">
                <label>
                    <input type="checkbox" value="remember-me"> 记住我
                </label>
                <label id="serverMes"></label>
            </div>
            <button class="btn btn-lg btn-primary btn-block" type="submit">登陆</button>            

        }

    </div> <!-- /container -->
</body>
</html>
<script type="text/javascript">
    $(function () {
        $(".validataCode").click(function () {
            replaceVcode();
        })
    })
    //重置验证码
    function replaceVcode() {
        $("#ImageCode").attr("src", $("#ImageCode").attr("src")+1); <span style="white-space:pre">					//$("#ImageCode").attr("src", '@Url.Action("Vcode", "Vcode")?rid=' + Math.random());
    }
    function afterLogin(data) { //

        var serverData = data.split(":"); //对请求返还的出数据进行处理;例如这条数据(ok:登陆成功)
        if (serverData[0] == "ok") {
            $("#serverMes").text(serverData[1]);
            window.location.href = "/Login/Login"; //如果登陆成功(ok)就跳转到主页
        } else if (serverData[0] == "no") { 
            $("#serverMes").text(serverData[1]); //提示错误
            replaceVcode(); //刷新验证码
        }
    }
</script>


BLL层中的UserInfoService.cs方法   (BLL层调用DAL层)

using Itcast.CMS.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Itcast.CMS.BLL
{
    public class UserInfoService
    {
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="userPwd">用户密码</param>
        /// <returns></returns>
        public  UserInfo GetUserInfo(string userName,string userPwd,string userMail)
        {
            Itcast.CMS.DAL.UserInfoDal userInfoDal = new DAL.UserInfoDal();
            return userInfoDal.GetUserInfo(userName, userPwd, userMail); //调用DAL层中的方法
        }
    }
}

DAL层中的UserInfoDal.cs类  (DAL层访问数据库)

using Itcast.CMS.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Itcast.CMS.DAL
{
    /// <summary>
    /// 验证用户名与密码是否正确
    /// </summary>
    public class UserInfoDal
    { 
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="userPwd">用户密码</param>
        /// <returns>UserInfo类对象</returns>
        public UserInfo GetUserInfo(string userName,string userPwd,string userMail)
        {
            DbHelperSQL db = new DbHelperSQL();
            SqlParameter[]param={new SqlParameter("@username",SqlDbType.NVarChar,100),new SqlParameter("@userpwd",SqlDbType.VarChar,100),new SqlParameter("@usermail",SqlDbType.VarChar,100)};
            param[0].Value = userName;
            param[1].Value = userPwd;
            param[2].Value = userMail;

            DataTable dt = db.GetDataTable("select * from T_UserInfo where (UserName=@username or @UserMail=@usermail) and UserPwd=@userpwd  ", param);

            UserInfo userinfo = null;
            if (dt.Rows.Count>0)
            {
                userinfo=new UserInfo();
                DataTableToEtity(userinfo,dt);
            }
            return userinfo;

        }
        /// <summary>
        /// DataTable转UserInfo实体
        /// </summary>
        /// <param name="dt">表名</param>
        /// <returns>UserInfo类对象</returns>
        public void DataTableToEtity(UserInfo user,DataTable dt)
        {           
            user.Id = Convert.ToInt32(dt.Rows[0]["Id"]);
            user.UserName = dt.Rows[0]["UserName"].ToString();
            user.UserPwd = dt.Rows[0]["UserPwd"].ToString();
            user.UserMail = dt.Rows[0]["UserMail"].ToString();
            user.RegTime = (DateTime)dt.Rows[0]["RegTime"];
        }
    }
}

Model层中 UserInfo.cs类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Itcast.CMS.Model
{
    public class UserInfo
    {
        /// <summary>
        /// 用户编号
        /// </summary>
        public int Id { get; set; }
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; }
        /// <summary>
        /// 用户密码
        /// </summary>
        public string UserPwd { get; set; }
        /// <summary>
        /// 用户邮箱
        /// </summary>
        public string UserMail { get; set; }
        /// <summary>
        /// 添加用户的时间
        /// </summary>
        public DateTime RegTime  { get; set; }
       
    }
}

验证码:ValidateCode.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Drawing.Imaging;

namespace bigtree.Actions
{
    public class ValidateCode
    {
        //// <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();
            }
        }
    }
}


==========================================

改成MVC 视图返回一副验证码  FileResult

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApp.Controllers
{
    public class TestController : Controller
    {
        //
        // GET: /Test/

        public ActionResult Index()
        {
            return View();

        }
        //--------------一般情况我们只要调用个CreateValidateGraphic方法,传入一个验证码的长度,就可以获取验证码的的图片了

        /// <summary>
        /// 创建验证码的图片
        /// </summary>
        /// <param name="length">验证码的长度</param>
        /// <returns>验证码图片</returns>
        public FileResult CreateValidateGraphic(int length)
        {
            string validateCode = EmptyResultDemo(length);
            Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), 22);
            Graphics g = Graphics.FromImage(image);

            //生成随机生成器  
            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);

            byte[] imageBuffer;
            //保存图片数据  
            using (MemoryStream stream = new MemoryStream())
            {
                //保存的二进制写入到stream对象中
                image.Save(stream, ImageFormat.Jpeg);

                //ms对象中的二进制数据转换成byte数组
                imageBuffer = stream.ToArray();
            }
            return File(imageBuffer, "image/jpeg");
        }

        /// <summary>
        /// 产生验证码的随机数
        /// </summary>
        /// <param name="length">验证码的长度</param>
        /// <returns>验证码</returns>
        public string EmptyResultDemo(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;

        }
    }
}

这个验证码使用方法

<img src="/Test/CreateValidateGraphic?length=5"/>   这样就可以获取一副验证码了。 参数5是,验证码的长度





评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值