首页 技术 正文
技术 2022年11月15日
0 收藏 731 点赞 3,881 浏览 17990 个字

快过年了,公司事情忙,好几天没有继续写博客,今天开始写账户模块系统登录,账户管理以及登录日志,

首先新建登录日志数据表:

USE [MVCSystem]
GO/****** Object: Table [dbo].[UsersLoginLogs] Script Date: 01/29/2016 15:28:02 ******/
SET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GOCREATE TABLE [dbo].[UsersLoginLogs](
[UsersLoginLogID] [int] IDENTITY(1,1) NOT NULL,
[UsersID] [int] NULL,
[LoginAddress] [nvarchar](50) NULL,
[LoginIP] [nvarchar](50) NULL,
[LoginTime] [datetime2](7) NULL,
[LoginInfo] [nvarchar](50) NULL,
CONSTRAINT [PK_UsersLoginLogs] PRIMARY KEY CLUSTERED
(
[UsersLoginLogID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]GO

然后更改模型:AccountModels.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Globalization;
using System.Web.Security;namespace MVCSystem.Web.Models
{ public class RegisterExternalLoginModel
{
[Required]
[Display(Name = "用户名")]
public string UserName { get; set; } public string ExternalLoginData { get; set; }
} public class LocalPasswordModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "当前密码")]
public string OldPassword { get; set; } [Required]
[StringLength(, ErrorMessage = "{0} 必须至少包含 {2} 个字符。", MinimumLength = )]
[DataType(DataType.Password)]
[Display(Name = "新密码")]
public string NewPassword { get; set; } [DataType(DataType.Password)]
[Display(Name = "确认新密码")]
[Compare("NewPassword", ErrorMessage = "新密码和确认密码不匹配。")]
public string ConfirmPassword { get; set; }
} public class LoginModel
{
[Required]
[Display(Name = "用户名")]
public string UserName { get; set; } [Required]
[DataType(DataType.Password)]
[Display(Name = "密码")]
public string Password { get; set; }
/// <summary>
/// 验证码
/// </summary>
[Required(ErrorMessage = "请输入验证码")]
[StringLength(, MinimumLength = , ErrorMessage = "验证码错误")]
public string ValidateCode { get; set; } [Display(Name = "记住我?")]
public bool RememberMe { get; set; }
} public class RegisterModel
{
[Required]
[Display(Name = "用户名")]
public string UserName { get; set; } [Required]
[StringLength(, ErrorMessage = "{0} 必须至少包含 {2} 个字符。", MinimumLength = )]
[DataType(DataType.Password)]
[Display(Name = "密码")]
public string Password { get; set; } [DataType(DataType.Password)]
[Display(Name = "确认密码")]
[Compare("Password", ErrorMessage = "密码和确认密码不匹配。")]
public string ConfirmPassword { get; set; }
} public class ExternalLogin
{
public string Provider { get; set; }
public string ProviderDisplayName { get; set; }
public string ProviderUserId { get; set; }
}
}

创建登录日志模型:M_UsersLoginLogs.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;namespace MVCSystem.Web.Models
{
[Table("UsersLoginLogs")]
public class M_UsersLoginLogs
{
[Key]
public int UsersLoginLogID { get; set; }
public int UsersID { get; set; }
public string LoginAddress { get; set; }
public string LoginIP { get; set; }
public DateTime? LoginTime { get; set; }
public string LoginInfo { get; set; } }
}

同样的,MVCSystemContext.cs加上 public DbSet<M_UsersLoginLogs> DB_UsersLoginLogs { get; set; }这句,然后创建账户管理的控制器

AccountController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using DotNetOpenAuth.AspNet;
using Microsoft.Web.WebPages.OAuth;
using WebMatrix.WebData;
using MVCSystem.Web.Filters;
using MVCSystem.Web.Models;
using MVCSystem.Web.Common;
using System.Drawing;
using System.Drawing.Drawing2D;namespace MVCSystem.Web.Areas.Admin.Controllers
{
[Authorize]
[InitializeSimpleMembership]
public class AccountController : BaseController
{
//
// GET: /Account/Login [AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
} //
// POST: /Account/Login [HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, M_UsersLoginLogs userLogs, string returnUrl)
{
if (Session["ValidateImgCode"] != null && string.Equals(Session["ValidateImgCode"].ToString(),
model.ValidateCode, StringComparison.OrdinalIgnoreCase))
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
var usersId = db.DB_UserProfiles.Single(u => u.UserName == model.UserName).UserId;//登录日志
userLogs.UsersID = usersId;
userLogs.LoginAddress = IpHelper.GetAdrByIp(IpHelper.GetRealIP());
userLogs.LoginIP = IpHelper.GetRealIP();
userLogs.LoginTime = DateTime.Now;
userLogs.LoginInfo = IpHelper.GetBrowerVersion();
db.DB_UsersLoginLogs.Add(userLogs);
db.SaveChanges(); return RedirectToLocal(returnUrl);
} // 如果我们进行到这一步时某个地方出错,则重新显示表单
ModelState.AddModelError("", "提供的用户名或密码不正确。");
return View(model);
}
else { ModelState.AddModelError("", "验证码错误");
return View(model);
}
} //
// POST: /Account/LogOff [HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
WebSecurity.Logout(); return RedirectToAction("Login", "Account");
}
#region 验证码
/// <summary>
/// 功能:返回验证码图片
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public ActionResult ValidateImg()
{
Color color1 = new Color();
//---------产生随机6位字符串
Random ran = new Random();
char[] c = new char[];
char[] ou = new char[];
int n = ;
for (int i = ; i < ; i++)
{
c[n] = (char)i;
n++;
}
for (int j = ; j < ; j++)
{
c[n] = (char)j;
n++;
}
for (int k = ; k < ; k++)
{
c[n] = (char)k;
n++;
}
foreach (char ch in c)
{
Console.WriteLine(ch);
}
string outcode = "";
for (int h = ; h < ; h++)
{
ou[h] = c[ran.Next()];
outcode += ou[h].ToString();
}
//
Session["ValidateImgCode"] = outcode; //1.创建一个新的图片,大小为(输入的字符串的长度*12),22
System.Drawing.Bitmap bmap = new System.Drawing.Bitmap(outcode.Length * , ); //2.定义画图面板,基于创建的新图片来创建
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmap); //3.由于默认的画图面板背景是黑色,所有使用clear方法把背景清除,同时把背景颜色设置为白色
g.Clear(System.Drawing.Color.White); // 画图片的背景噪音线
for (int i = ; i < ; i++)
{
int x1 = ran.Next(bmap.Width);
int x2 = ran.Next(bmap.Width);
int y1 = ran.Next(bmap.Height);
int y2 = ran.Next(bmap.Height);
g.DrawLine(new Pen(color1), x1, y1, x2, y2);
} // 画图片的前景噪音线
for (int i = ; i < ; i++)
{
int x = ran.Next(bmap.Width);
int y = ran.Next(bmap.Height);
bmap.SetPixel(x, y, Color.FromArgb(ran.Next()));
} //4.使用DrawString 方法把要输出的字符串输出到画板上。输出的字符从参数(outcode)内获得。
Font font = new Font("Arial", , FontStyle.Bold | FontStyle.Italic);
LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(, , bmap.Width, bmap.Height), Color.Blue, Color.DarkRed, 1.2f, true);
g.DrawString(outcode, font, brush, , ); //5.定义一个内存流,把新创建的图片保存到内存流内,这样就不用保存到磁盘上,提高了速度。
System.IO.MemoryStream ms = new System.IO.MemoryStream(); //6.把新创建的图片保存到内存流中,格式为jpeg的类型
bmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); //7.输出这张图片,由于此页面的 ContentType="image/jpeg" 所以会输出图片到客户端。同时输出是以字节输出,所以要把内存流转换为字节序列,使用ToArray()方法。
Response.BinaryWrite(ms.ToArray());
return View();
}
#endregion //
// GET: /Account/Manage
/// <summary>
/// 密码重置
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public ActionResult Manage(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "<script>alert('密码修改成功!');</script>" : "";
ViewBag.HasLocalPassword = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
ViewBag.ReturnUrl = Url.Action("Manage");
return View();
} //
// POST: /Account/Manage [HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Manage(LocalPasswordModel model)
{
bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
ViewBag.HasLocalPassword = hasLocalAccount;
ViewBag.ReturnUrl = Url.Action("Manage");
if (hasLocalAccount)
{
if (ModelState.IsValid)
{
// 在某些出错情况下,ChangePassword 将引发异常,而不是返回 false。
bool changePasswordSucceeded;
try
{
changePasswordSucceeded = WebSecurity.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword);
}
catch (Exception)
{
changePasswordSucceeded = false;
} if (changePasswordSucceeded)
{
return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
}
else
{ ModelState.AddModelError("", "当前密码不正确或新密码无效!");
}
}
}
else
{
// 用户没有本地密码,因此将删除由于缺少
// OldPassword 字段而导致的所有验证错误
ModelState state = ModelState["OldPassword"];
if (state != null)
{
state.Errors.Clear();
} if (ModelState.IsValid)
{
try
{
WebSecurity.CreateAccount(User.Identity.Name, model.NewPassword);
return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
}
catch (Exception)
{
ModelState.AddModelError("", String.Format("无法创建本地帐户。可能已存在名为“{0}”的帐户。", User.Identity.Name));
}
}
} // 如果我们进行到这一步时某个地方出错,则重新显示表单
return View(model);
} #region 帮助程序
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
} public enum ManageMessageId
{
ChangePasswordSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
} internal class ExternalLoginResult : ActionResult
{
public ExternalLoginResult(string provider, string returnUrl)
{
Provider = provider;
ReturnUrl = returnUrl;
} public string Provider { get; private set; }
public string ReturnUrl { get; private set; } public override void ExecuteResult(ControllerContext context)
{
OAuthWebSecurity.RequestAuthentication(Provider, ReturnUrl);
}
} #endregion
}
}

视图Account/Manage.cshtml【账户管理】

@model MVCSystem.Web.Models.LocalPasswordModel
@{
ViewBag.Title = "Manage";
Layout = "~/Areas/Admin/Views/Shared/_Layout_Admin.cshtml";
}
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<div class="container">
@Html.Raw(ViewBag.StatusMessage)
<table class="table table-bordered" >
<tr>
<td width="10%" class="tableleft">旧密码</td>
<td> @Html.PasswordFor(m => m.OldPassword) @Html.ValidationMessageFor(model => model.OldPassword)</td>
</tr>
<tr>
<td width="10%" class="tableleft">新密码</td>
<td> @Html.PasswordFor(m => m.NewPassword) @Html.ValidationMessageFor(model => model.NewPassword)</td>
</tr>
<tr>
<td width="10%" class="tableleft">确认密码</td>
<td> @Html.PasswordFor(m => m.ConfirmPassword) @Html.ValidationMessageFor(model => model.ConfirmPassword)</td>
</tr>
<tr>
<td class="tableleft"></td>
<td>
<button type="submit" class="button button-primary">修改密码</button>
</td>
</tr>
</table>
</div>
}

然后添加账户管理菜单,无需多说,这个大家懂

接下来是登录功能,首先看看视图Account/Login.cshtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
@model MVCSystem.Web.Models.LoginModel
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<title>登录</title>
<link href="~/Content/Css/style.css" rel="external nofollow" rel="stylesheet" />
<link href="~/Content/Css/login.css" rel="external nofollow" rel="stylesheet" />
<style type="text/css">
.inner
{
position:relative;
}
.inner .field-validation-error
{
position:absolute;top:-10px;left:100px;
color:#f00;
}
#RememberMe
{
width:15px;height:15px;
margin-top:7px;
}
.validation-summary-errors
{
position:absolute;
top:10px;
right:50%;
color:#f00;
}
#ValidateCode
{
width:100px;
}
</style>
</head>
<body>
@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) { <div class="w_body">
<div class="bodyBg"><img src="~/Content/Images/loginBodyBg.png" /></div>
<div class="whiteBg"></div>
<div class="center">
<div class="titleBg"></div>
<div class="login">
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<div class="form">
<div class="inner p_clearfix"><label for="user">账&nbsp;&nbsp;号:</label> @Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)</div>
<div class="inner p_clearfix"><label for="pword">密&nbsp;&nbsp;码:</label>@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)</div>
<div class="inner p_clearfix"><label for="pword">验证码:</label> @Html.TextBoxFor(m => m.ValidateCode, new { @placeholder = "6位数的验证码" })
<img src="/Admin/Account/ValidateImg" id="validimg" height="34" alt="验证码" title="看不清?,换一张" style="cursor:pointer;float:left;" onclick="ShowValidate()" />
@Html.ValidationMessageFor(m => m.ValidateCode)
</div>
<div class="inner p_clearfix checkboxCom">
<label for="pword">记住我:</label> @Html.CheckBoxFor(m => m.RememberMe)
</div>
<button type="submit" title="登录" class="loginBtn p_i"></button>
</div>
</div>
<div class="copyRight">Copyright ©2012 网站角色权限管理系统 滇ICP备xxxxxxx号</div>
</div>
</div>
}
</body>
</html>
<script src="~/Content/assets/js/jquery-1.8.1.min.js"></script>
<script type="text/javascript">
function ShowValidate() {
$("#validimg").get(0).src = '/Admin/Account/ValidateImg?time=' + (new Date()).getTime();
}</script>

他们用的css样式表,以及背景图,下面给出来,大家复制下去就可以用了

Content/Css/login.css

@charset "utf-8";.w_body .bodyBg{ position: fixed; bottom:; left:; z-index: -999; overflow: hidden; width: 100%; height: 100%; min-height: 100%; _position: absolute;}
.w_body .bodyBg img { width: 100%; height: 100%;}
.w_body { background: #286ea7 url(/Content/Images/loginBodyBg.png) center no-repeat; height:100%; width: 100%; position: fixed; left:; bottom:; z-index: -999;}
.w_body .whiteBg { width: 100%; height: 217px; position: relative; top: 245px; background-color: #fff;}
.w_body .center { width: 595px; margin: 0 auto; position: relative; top: -217px;}
.w_body .titleBg { width: 392px; height: 55px; position: absolute; top: 140px; left: 100px; background-image: url(/Content/Images/title.png); background-repeat: no-repeat;}
.w_body .login { width: 595px; height: 232px; position: absolute; top: 245px; left:; right:; margin: auto; background-image: url(/Content/Images/loginBg.png); background-repeat: no-repeat;}
.w_body .login .form { width: 360px; float: left; margin: 50px 0 0 40px;}
.w_body .login .form .inner { margin: 10px 0; padding-bottom: 35px; line-height: 28px;}
.w_body .login .form .inner label { display: block; float: left; width: 90px; font-size: 14px; color: #525252; text-align: right;}
.w_body .login .form .inner input { float: left; border: 1px solid #ddd; width: 220px; height: 20px; line-height: 20px; padding: 5px;}
.w_body .login .form .inner .w { width: 80px;}
.w_body .login .form .inner a { margin-left: 20px;}
.w_body .login .form .loginBtn {cursor:pointer; display: block; width: 135px; height: 135px;border:0 none; position: absolute; top: 50px; right: 70px; background-image: url(/Content/Images/loginBtn.png); background-repeat: no-repeat;}
.w_body .copyRight { width: 595px; color: #fff; text-align: center; position: absolute; top: 500px; left:; right:; margin: auto;}

Content/Css/style.css

@charset "utf-8";
body{
font-size: 13px;
}
select, textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input {
padding: 1px;
}select {
height: 24px;
}.radio{
font-size: 11px;
margin-bottom: 4px;
}.nav{
margin-bottom: 5px;
}form{
margin: 0 0 5px;
}.page{
text-align: right;margin-right:25px;margin-top:5px;
}.page a{
margin-left: 5px;
}.page .current{
margin-left: 5px;
color: red;
}.table td input[type="checkbox"]{
padding:;
margin:;
}.table th input[type="checkbox"]{
padding:;
margin:;
}.table td, .table th{
padding-top: 8px;
padding-bottom: 4px;
line-height:20px;}
.table th{ background-color:#eaeaea;
}.definewidth{
width:96%;
margin:auto;
}
.m10{
margin-top:10px;
}
.m20{
padding-top:20px;
}
.bui-grid-cell-text a
{
padding-right:10px;
}
.tableleft{
text-align:right;
padding-left:5px;
background-color:#f5f5f5;}
.text-center{ text-align: center;}
.text-left{ text-align: left;}
.text-right{ text-align: right;}
/*浮动样式 S*/
.L { float: left;}
.R { float: right;}
/*浮动样式 E*/
/*清除浮动 S*/
.clearfix { #zoom:; }
.clearfix:after { content:'.'; height:; line-height:; display:block; clear:both; visibility:hidden; }
.clear{ clear:both;margin:0 auto; overflow:hidden;}
/*清除浮动 E*//*formValidator�����֤*/
.onShow,.onFocus,.onError,.onCorrect,.onLoad,.onTime{display:inline-block;display:-moz-inline-stack;zoom:;*display:inline; vertical-align:middle;background:url(../Images/msg_bg.png) no-repeat; color:#444;line-height:18px;padding:2px 10px 2px 23px; margin-left:10px;_margin-left:5px}
.onShow{background-position:3px -147px;border-color:#40B3FF;color:#959595}
.onFocus{background-position:3px -147px;border-color:#40B3FF;}
.onError{background-position:3px -47px;border-color:#40B3FF; color:red}
.onCorrect{background-position:3px -247px;border-color:#40B3FF;}
.onLamp{background-position:3px -200px}
.onTime{background-position:3px -1356px}
/*上传附件*/
.fileCom
{
position:relative;
float:left;
width:220px;
padding:3px 5px;
background-color:#6CB5F4;
border-radius:4px;
margin-right:10px;
overflow:hidden;
}
.fileStr
{
position:absolute;
left:65px;
cursor:pointer;
width:500px;
height:20px;
line-height:20px;
background-color:#6CB5F4;
padding:5px;
top:; color:#fff;
}
#textFile
{
width:220px; overflow:hidden;
}
.imgCom
{
float:left;padding-right:10px;
}

以及背景图:链接: http://pan.baidu.com/s/1ge0e4GN 密码: urqv。下载后放到Content/Images/

这里的登录页面需要输入验证码,我们需要添加一个空的视图来临时存放每次生成的验证码图片:

Account/ValidateImg.cshtml

@{
Layout = null;
}

接着需要创建一个登录日志ip地址获取的帮助类,我们把它放到common这个存放公共类的文件夹中:

IpHelper.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;namespace MVCSystem.Web.Common
{
public class IpHelper
{
/// <summary>
/// 通过IP得到IP所在地省市(Porschev)
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static string GetAdrByIp(string ip)
{
string url = "http://www.cz88.net/ip/?ip=" + ip;
string regStr = "(?<=<span\\s*id=\\\"cz_addr\\\">).*?(?=</span>)"; //得到网页源码
string html = GetHtml(url);
Regex reg = new Regex(regStr, RegexOptions.None);
Match ma = reg.Match(html);
html = ma.Value;
string[] arr = html.Split(' ');
return arr[];
}
/// <summary>
/// 获取当前Ip所在地址
/// </summary>
/// <returns></returns>
public static string GetAdrByIp()
{
string address = GetAdrByIp(GetRealIP());
return address == "" ? "中国" : address;
} /// <summary>
/// 获取HTML源码信息(Porschev)
/// </summary>
/// <param name="url">获取地址</param>
/// <returns>HTML源码</returns>
public static string GetHtml(string url)
{
string str = "";
try
{
Uri uri = new Uri(url);
WebRequest wr = WebRequest.Create(uri);
Stream s = wr.GetResponse().GetResponseStream();
StreamReader sr = new StreamReader(s, Encoding.Default);
str = sr.ReadToEnd();
}
catch (Exception e)
{
}
return str;
} /// <summary>
/// 获得客户端的IP
/// </summary>
/// <returns>当前客户端的IP</returns>
public static string GetRealIP()
{
string strIP = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (strIP == null || strIP.Length < )
{
strIP = HttpContext.Current.Request.UserHostAddress;
}
if (strIP == null || strIP.Length < )
{
return "0.0.0.0";
}
return strIP;
}
/// <summary>
/// 获取浏览器的版本以及名称
/// </summary>
/// <returns></returns>
public static string GetBrowerVersion()
{
string browerVersion = string.Empty;
if (System.Web.HttpContext.Current != null)
{
System.Web.HttpBrowserCapabilities browser = System.Web.HttpContext.Current.Request.Browser;
if (browser != null)
{
browerVersion = browser.Browser + browser.Version;
}
}
return browerVersion;
}
}
}

最后大道登录后才能访问页面在各个视图中添加授权标识 [Authorize]

namespace MVCSystem.Web.Areas.Admin.Controllers
{
[Authorize]
public class HomeController : BaseController
{

大功告成,接下来看运行效果:

ASP.NET MVC4.0+EF+LINQ+bui+网站+角色权限管理系统(6)

然后根据之前添加的用户账户

可以登录了,然后查看登录日志数据表,可以看到一条登录日志

ASP.NET MVC4.0+EF+LINQ+bui+网站+角色权限管理系统(6)

登录日志管理,这里就不写了,大家可以动手写下!

源码下载:http://www.yealuo.com/Sccnn/Detail?KeyValue=2f926407-f80b-4bff-a729-949a53efed7b

作者:boyzi007

出处:http://www.cnblogs.com/boyzi/

QQ:470797533

QQ交流群:364307742
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,967
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,487
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,332
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,115
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,748
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,783