ASP.NET MVC5入门3之登录验证
参考:
HTML页面模版:
http://www.ui.cn/detail/70262.html(第38个)
MVC后台代码参考:
http://www.oschina.net/p/nfine
开发环境:
IDE:VS2013
架构:ASP.NET MVC5
语言:C#
代码下载:http://download.csdn.net/detail/u010312811/9809942
1. 效果图

2.项目结构
解决方案包含两个工程文件:
- MvcLogin:默认创建的工程,是MVC架构的主体。该工程主要包含LoginController、Login/Index、LocalStyle文件夹,分别对应控制器、视图和应用于该工程的样式和js。
- MvcLogin.Methods:方法库,工程本身是一个类库,可以存放一些常用的方法,可以方便代码复用。此处涉及到登录时验证码的获取、登陆验证(通过Ajax),方法均存放在 该类库中。


3. CSS及jQuery
3.1 LocalStyle/CSS/LoginStyle.css文件
代码:
@import url(http://fonts.googleapis.com/css?family=Tenor+Sans);
html {
background-color: #5D92BA;
font-family: "Tenor Sans", sans-serif;
}
.container {
width: 500px;
height: 400px;
margin: 0 auto;
}
.login {
/*margin-top: 50px;*/
margin-top:30%;
width: 450px;
}
.login-heading {
font: 1.8em/48px "Tenor Sans", sans-serif;
color: white;
}
.input-txt {
width: 100%;
padding: 20px 10px;
background: #5D92BA;
border: none;
font-size: 1em;
color: white;
border-bottom: 1px dotted rgba(250, 250, 250, 0.4);
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-moz-transition: background-color 0.5s ease-in-out;
-o-transition: background-color 0.5s ease-in-out;
-webkit-transition: background-color 0.5s ease-in-out;
transition: background-color 0.5s ease-in-out;
}
.input-txt:-moz-placeholder {
color: #81aac9;
}
.input-txt:-ms-input-placeholder {
color: #81aac9;
}
.input-txt::-webkit-input-placeholder {
color: #81aac9;
}
.input-txt:focus {
background-color: #4478a0;
}
.login-footer {
margin: 10px 0;
overflow: hidden;
float: left;
width: 100%;
}
.btn {
padding: 15px 30px;
border: none;
background: white;
color: #5D92BA;
}
.btn--right {
float: right;
}
.icon {
display: inline-block;
}
.icon--min {
font-size: .9em;
}
.lnk {
font-size: .8em;
line-height: 3em;
color: white;
text-decoration: none;
}
此部分代码不做介绍,均引自Simple Login Form项目
3.2 LocalStyle/Javascript/LoginScript文件
jQuery文件需要在html添加使用才可以使用,并且建议添加到body结束之前。
(function ($) {
$.login = {
formMessage: function (msg) {
$('.login_tips').find('.tips_msg').remove();
$('.login_tips').append('<div class="tips_msg"><i class=fa fa-question-circle></i>' + msg + '</div>');
},
loginClick: function () {
var $username = $("#username");
var $password = $("#password");
var $code = $("#validateCode");
if ($username.val() == "") {
$username.focus();
$.login.formMessage('请输入用户名');
return false;
}
else if ($password.val() == "") {
$password.focus();
$.login.formMessage('请输入登录密码');
return false;
}
else if ($code.val() == "") {
$code.focus();
$.login.formMessage('请输入验证码');
return false;
}
else {
$.login.formMessage('');
$("#loginButton").attr('disabled', 'disabled').find('span').html("验证中...");
$.ajax({
url: "/Login/CheckLogin",
data: { username: $.trim($username.val()), password: $.trim($password.val()), code: $.trim($code.val()) },
type: "post",
dataType: "json",
success: function (data) {
if (data.state == "success") {
$("#loginButton").find('span').html("登录成功,正在跳转...");
window.setTimeout(function () {
window.location.href = "/Home/Index";
}, 500);
}
else {
$("#loginButton").removeAttr('disabled').find('span').html("登录");
$("#switchCode").trigger("click");
$code.val('');
$.login.formMessage(data.message);
}
}
});
}
},
init: function () {
$("#switchCode").click(function () {
$("#imgCode").attr("src", "/Login/GetAuthCode?time=" + Math.random());
});
$("#loginButton").click(function () {
$.login.loginClick();
});
}
};
$(function () {
$.login.init();
});
})(jQuery);
- 4~7行:定义函数formMessage:用于修改错误提示信息;
- 9~56行:定义函数loginClick:用于响应登录按键的点击事件;
- 35~54行:通过ajax同服务器通信,对用户名、密码及验证码的信息进行验证;
- 58~65行:初始化函数,为switchCode添加切换验证码的功能,为loginButton添加登录验证的功能。
注:
(1)在第60行的代码中,请求验证码时传入了time属性,这是根据数据路由规定的,因为MVC的默认使用传统路由。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
该路由协议中规定了id是作为必须的参数,因而尽管在验证码的获取函数中没有参数,此处仍需要多传一个参数过去,才能满足路由协议。详见ASP.NET MVC5高级编程 之 路由
至于第60行使用time,这个可以使用其他字符串替换,如ti。
(2)在$.login中包含三个函数,每个函数的结束使用","进行分割,最后一个函数结束后可以不加。
$.login结束后后使用分号结尾。
(3)第5行、第6行使用jQuery的遍历和Html方法进行元素的查找和追加操作。
详见: jQuery HTML和jQuery 遍历
(4)loginClick函数中,用到了:
$username.focus();元素获取焦点;
$password.val():获取元素内容;
$password.val("字符串"):为元素赋值。
(5)Ajax(35~54行):url:调用控制器的相应方法;data:获取表单内容;type:采用post的方法;dataType:使用json。(json需要添加才能使用)
success:对服务器的返回数据进行处理,如果校验成功则跳转到主界面,否则对错误进行提示。
4 html文件
Views/Login/Index.cshtml文件定义了登陆界面的标签(当然需要依靠CSS文件才可以美化布局)
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width" />
<title>用户登录</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link href="~/LocalStyle/CSS/LoginStyle.css" rel="stylesheet" />
</head>
<body>
<div class="container">
<h1 class="login-heading">ASP.NET MVC5 登陆验证</h1>
<div class="login" >
<div>
<input type="text" name="username" id="username" placeholder="用户名"class="input-txt" required=""/>
</div>
<div>
<input type="password" name="password" id="password" placeholder="密码" class="input-txt" required=""/>
</div>
<div>
<input type="text" name="name" placeholder="验证码" style="width:190px;" id="validateCode" class="input-txt"/>
<div style="width:210px;float:right;padding-top:14px;padding-left:14px;">
看不清?<a id="switchCode" href="javascript:void();" style="text-decoration:none">换一张</a>
<img id="imgCode" class="authcode" src="~/Login/GetAuthCode" width="80" height="25" alt="换一个"/>
</div>
</div>
<div class="login-footer">
<a href="#" class="lnk">
<span>点击注册</span>
</a>
<button id="loginButton" type="button" class="btn btn--right"><span>登录</span></button>
</div>
<div class="login_tips" style="color:red;"></div>
</div>
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/LocalStyle/Javascript/LoginScript.js"></script>
</body>
</html>
(1)第1~3行:未使用布局页;
(2)第12~13行:添加对样式的引用;
(3)第42~43行:添加对jQuery的引用。
(4)第29行:src属性使得元素可以直接引用控制器中的方法。
5 控制器LoginController
public class LoginController : Controller
{
// GET: Login
public ActionResult Index()
{
return View();
}
public ActionResult GetAuthCode()
{
return File(new VerifyCode().GetVerifyCode(), @"image/Gif");
}
public ActionResult CheckLogin(string username,string password,string code)
{
try
{
if(username=="admin")
return Content(new AjaxResult { state = ResultType.success.ToString(), message = "登录成功。" }.ToJson());
")
return Content(new AjaxResult { state = ResultType.success.ToString(), message = "登录成功。" }.ToJson());
else
return Content(new AjaxResult { state = ResultType.error.ToString(), message = "请验证帐号及密码!" }.ToJson());
}
catch (Exception ex)
{
return Content(new AjaxResult { state = ResultType.error.ToString(), message = ex.Message }.ToJson());
}
}
(1)第4~7行:Login界面打开的默认方法;
(2)第9~12行:获取验证码,参数意义可查看函数定义;
(3)第14~30行:对表单传过来的数据进行判断,并通过json返回判断结果。此处千万注意,参数username、password和code需要和jQuery中传的字符串一定匹配,因为结果通过键值对进行匹配,如果名称不一致则无法判断。
如果jQuery传值user而控制器中以username参数名称接收数据,则无法接到用户名参数,因而第一个if(username=="admin")根本不会进行判断。
6 辅助方法
AjaxResult类文件:
public class AjaxResult
{
/// <summary>
/// 操作结果类型
/// </summary>
public object state { get; set; }
/// <summary>
/// 获取 消息内容
/// </summary>
public string message { get; set; }
/// <summary>
/// 获取 返回数据
/// </summary>
public object data { get; set; }
}
/// <summary>
/// 表示 ajax 操作结果类型的枚举
/// </summary>
public enum ResultType
{
/// <summary>
/// 消息结果类型
/// </summary>
info,
/// <summary>
/// 成功结果类型
/// </summary>
success,
/// <summary>
/// 警告结果类型
/// </summary>
warning,
/// <summary>
/// 异常结果类型
/// </summary>
error
}
Json类文件:
public static class Json
{
public static object ToJson(this string Json)
{
return Json == null ? null : JsonConvert.DeserializeObject(Json);
}
public static string ToJson(this object obj)
{
var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
return JsonConvert.SerializeObject(obj, timeConverter);
}
public static string ToJson(this object obj, string datetimeformats)
{
var timeConverter = new IsoDateTimeConverter { DateTimeFormat = datetimeformats };
return JsonConvert.SerializeObject(obj, timeConverter);
}
public static T ToObject<T>(this string Json)
{
return Json == null ? default(T) : JsonConvert.DeserializeObject<T>(Json);
}
public static List<T> ToList<T>(this string Json)
{
return Json == null ? null : JsonConvert.DeserializeObject<List<T>>(Json);
}
public static DataTable ToTable(this string Json)
{
return Json == null ? null : JsonConvert.DeserializeObject<DataTable>(Json);
}
public static JObject ToJObject(this string Json)
{
return Json == null ? JObject.Parse("{}") : JObject.Parse(Json.Replace(" ", ""));
}
}
VerifyCode文件:
public class VerifyCode
{
public byte[] GetVerifyCode()
{
;
;
;
string chkCode = string.Empty;
//颜色列表,用于验证码、噪线、噪点
Color[] color = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };
//字体列表,用于验证码
string[] font = { "Times New Roman" };
//验证码的字符集,去掉了一些容易混淆的字符
', 'a', 'b', 'd', 'e', 'f', 'h', 'k', 'm', 'n', 'r', 'x', 'y', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W', 'X', 'Y' };
Random rnd = new Random();
//生成验证码字符串
; i < ; i++)
{
chkCode += character[rnd.Next(character.Length)];
}
//写入Session、验证码加密
//WebHelper.WriteSession("nfine_session_verifycode", Md5.md5(chkCode.ToLower(), 16));
//创建画布
Bitmap bmp = new Bitmap(codeW, codeH);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);
//画噪线
; i < ; i++)
{
int x1 = rnd.Next(codeW);
int y1 = rnd.Next(codeH);
int x2 = rnd.Next(codeW);
int y2 = rnd.Next(codeH);
Color clr = color[rnd.Next(color.Length)];
g.DrawLine(new Pen(clr), x1, y1, x2, y2);
}
//画验证码字符串
; i < chkCode.Length; i++)
{
string fnt = font[rnd.Next(font.Length)];
Font ft = new Font(fnt, fontSize);
Color clr = color[rnd.Next(color.Length)];
g.DrawString(chkCode[i].ToString(), ft, , ();
}
//将验证码图片写入内存流,并将其以 "image/Png" 格式输出
MemoryStream ms = new MemoryStream();
try
{
bmp.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
catch (Exception)
{
return null;
}
finally
{
g.Dispose();
bmp.Dispose();
}
}
}
ASP.NET MVC5入门3之登录验证的更多相关文章
- Asp.Net MVC5入门学习系列⑥
原文:Asp.Net MVC5入门学习系列⑥ 接着上次的篇幅,我们这篇手动来写一个查询的流程代码! 搜索/查询 流程功能的实现 那现在要做搜索(查询)功能我们第一步应该做什么呢!第一次是不是我们应该去 ...
- ASP.NET MVC5入门1之项目创建
本博文参考ASP.NET MVC5入门指南,下载链接: ASP.NET_MVC5_入门指南 1.创建项目 文件 --> 新建 --> 项目 Visual C# --> Web --& ...
- Asp.Net MVC5入门学习系列③
原文:Asp.Net MVC5入门学习系列③ 添加一个视图(View) 接着上篇的入门系列,上面解说添加一个简单Controller(控制器),这里我们简单的在来添加一个View(视图)来展示我们Co ...
- Asp.Net MVC5入门学习系列②
原文:Asp.Net MVC5入门学习系列② 添加一个Controller(控制器) 因为我们用的是Asp.Net MVC,MVC最终还是一套框架,所以我们还是需要遵循它才能玩下去,或者说是更好的利用 ...
- Asp.Net MVC5入门学习系列①
原文:Asp.Net MVC5入门学习系列① 现在直接开始MVC5的学习系列,学习资源来自Micrsoft. 开始使用Asp.Net MVC 5 打开Visual Studio 2013,然后新建一个 ...
- Asp.Net MVC5入门学习系列⑦
原文:Asp.Net MVC5入门学习系列⑦ 接着上篇结尾所说,如果开发中刚才遇到Model需要添加或者减少字段/属性的话,但是刚好你也利用EF的Code frist通过Model生存的数据库,这时改 ...
- Asp.Net MVC5入门学习系列⑤
原文:Asp.Net MVC5入门学习系列⑤ 检查VS生产的编辑方法和编辑窗体 前面我们一步使用强类型,然后创建Controller(控制器)的时候,VS默认已经给我们把CURD都简单的实现了.这篇的 ...
- Asp.Net MVC5入门学习系列④
原文:Asp.Net MVC5入门学习系列④ 添加Model且简单的使用EF 对于EF(EntityFramework)不了解的朋友可以去百度文科或者在园子里搜一些简资源看下,假如和我一样知道EF的概 ...
- ASP.NET + MVC5 入门完整教程八 -—-- 一个完整的应用程序(上)
https://blog.csdn.net/qq_21419015/article/details/80509513 SportsStore 1.开始创建Visual Studio 解决方案和项目这里 ...
随机推荐
- Python线程和协程-day10
写在前面 上课第10天,打卡: 感谢Egon老师细致入微的讲解,的确有学到东西! 一.线程 1.关于线程的补充 线程:就是一条流水线的执行过程,一条流水线必须属于一个车间: 那这个车间的运行过程就是一 ...
- kudu系列: Java API使用和效率测试
Kudu+Impala很适合数据分析, 但直接使用Insert values语句往Kudu表插入数据, 效率实在不好, 测试下来insert的速度仅为80笔/秒. 原因也是显然的, Kudu本身写入效 ...
- 酷狗.kgtemp文件加密算法逆向
该帖转载于孤心浪子--http://www.cnblogs.com/KMBlog/p/6877752.html 酷狗音乐上的一些歌曲是不能免费下载的,然而用户仍然可以离线试听,这说明有缓存文件,并且极 ...
- Android文字转语音引擎(TTS)使用
百度网盘下载地址 密码:3si0资源来源:https://blog.csdn.net/Sqq_yj/article/details/82460580?utm_source=blogxgwz4 简单比较 ...
- IScroll在某些手机浏览器上不能滑动和卡顿解决办法
1.不能滑动,增加一句 if (scroll != null) scroll.refresh();2.卡顿,增加 <script>window.PointerEvent = undefin ...
- Dictionary与SortedDictionary
Dictionary是无序的,如果想排序,需要使用SortDictionary. 下面是一个用法示例 //按照某个字段排序 public void SortByCardItem(string item ...
- 基于DSP的IS95正向业务信道模块设计
**定时20ms循环处理话音数据包*** *伪指令不占空间不影响执行速度,只是定义和描述但对汇编链接有重要指示作用 ********************************* .title & ...
- Linux 下磁盘挂载
Linux 磁盘挂载 新硬盘挂载: fdisk /dev/sdb p # 打印分区 d # 删除分区 n # 创建分区,(一块硬盘最多4个主分区,扩展占一个主分区位置.p主分区 e扩展) w # 保存 ...
- 腾讯云服务器ubuntu16.04系统下安装Python版本管理工具pyenv
一. 系统环境 腾讯云提供的系统是ubuntu 16.04 LTS,系统默认的Python版本是2.7.12,我想要安装3.6和其他的版本. 比较方便的是腾讯云已经默认安装好了git和curl ...
- webpack配置模块的查找范围
一般我们的入口文件会引入一下公共的样式文件,比如这样 import './style' 但是这个样式文件并不会生效呀,因为你的写法不对鸭,你要把文件的后缀名也要写 import './style.cs ...