一、默認(rèn)Web項目的更改
用戶這部分還是自己做,所以刪除自動生成的用戶相關(guān)代碼。
二、添加Member區(qū)域
在web項目上點(diǎn)右鍵 添加 區(qū)域Member。
添加Home控制器,選擇MVC5控制器-空
我們給public ActionResult Index()添加一個視圖,代碼很簡單就是顯示下用戶名
@{
ViewBag.Title = "會員中心";
}
h2>歡迎你!@User.Identity.Name
/h2>
我們先運(yùn)行一下,出錯啦。
這是因為項目中有兩個名為Home的控制器,必須在路由中加上命名空間。先打開區(qū)域中的MemberAreaRegistration添加命名空間。
再打開項目中的RouteConfig,添加命名空間
再刷新瀏覽器,可以正常顯示。
再添加用戶控制器UserController。
三、模型類的更改
在這里先對Models項目User模型進(jìn)行修改,原來考慮的是每個用戶只能屬于一個用戶組,后來仔細(xì)考慮了一下,還是不太合適,比如一個用戶兼任多個角色,所以還是把用戶和用戶組改成一對多的關(guān)系。
- User模型。在模型中刪除GroupID,刪除外鍵Group。
- Role模型。原來UserGroup(用戶組)改為角色,考慮到權(quán)限管理感覺叫角色比叫戶組更加合適,另外角色的含義更廣,可以是指用戶組,也可以指職位,還可以指部門……修改后代碼如下:
using System.ComponentModel.DataAnnotations;
namespace Ninesky.Models
{
/// summary>
/// 角色
/// remarks>
/// 創(chuàng)建:2014.02.02
/// 修改:2014.02.16
/// /remarks>
/// /summary>
public class Role
{
[Key]
public int RoleID { get; set; }
/// summary>
/// 名稱
/// /summary>
[Required(ErrorMessage="必填")]
[StringLength(20, MinimumLength = 2, ErrorMessage = "{1}到{0}個字")]
[Display(Name="名稱")]
public string Name { get; set; }
/// summary>
/// 角色類型br />
/// 0普通(普通注冊用戶),1特權(quán)(像VIP之類的類型),3管理(管理權(quán)限的類型)
/// /summary>
[Required(ErrorMessage = "必填")]
[Display(Name = "用戶組類型")]
public int Type { get; set; }
/// summary>
/// 說明
/// /summary>
[Required(ErrorMessage = "必填")]
[StringLength(50, ErrorMessage = "少于{0}個字")]
[Display(Name = "說明")]
public string Description { get; set; }
/// summary>
/// 獲取角色類型名稱
/// /summary>
/// returns>/returns>
public string TypeToString()
{
switch (Type)
{
case 0:
return "普通";
case 1:
return "特權(quán)";
case 2:
return "管理";
default:
return "未知";
}
}
}
}
UserRoleRelation類。在Models項目添加角色關(guān)系類UserRoleRelation類,代碼:
using System.ComponentModel.DataAnnotations;
namespace Ninesky.Models
{
/// summary>
/// 用戶角色關(guān)系
/// remarks>
/// 創(chuàng)建:2014.02.16
/// /remarks>
/// /summary>
public class UserRoleRelation
{
[Key]
public int RelationID { get; set; }
/// summary>
/// 用戶ID
/// /summary>
[Required()]
public int UserID { get; set; }
/// summary>
/// 角色I(xiàn)D
/// /summary>
[Required()]
public int RoelID { get; set; }
}
}
NineskyDbContext類。 如下圖藍(lán)色框為修改部分,紅框為新增加
三、驗證碼及Sha256加密
1、驗證碼
現(xiàn)在驗證碼是網(wǎng)站的必須功能,我把驗證碼功能分成三塊:創(chuàng)建驗證碼字符、根據(jù)驗證碼生成圖片、User控制器action中保存驗證碼并返回圖片。
創(chuàng)建驗證碼字符 CreateVerificationText()
在Common中添加Security類,在類中利用偽隨機(jī)數(shù)生成器生成驗證碼字符串。
/// summary>
/// 創(chuàng)建驗證碼字符
/// /summary>
/// param name="length">字符長度/param>
/// returns>驗證碼字符/returns>
public static string CreateVerificationText(int length)
{
char[] _verification = new char[length];
char[] _dictionary = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
Random _random = new Random();
for (int i = 0; i length; i++) { _verification[i] = _dictionary[_random.Next(_dictionary.Length - 1)]; }
return new string(_verification);
}
根據(jù)驗證碼生成圖片CreateVerificationImage()
思路是使用GDI+創(chuàng)建畫布,使用偽隨機(jī)數(shù)生成器生成漸變畫刷,然后創(chuàng)建漸變文字。
/// summary>
/// 創(chuàng)建驗證碼圖片
/// /summary>
/// param name="verificationText">驗證碼字符串/param>
/// param name="width">圖片寬度/param>
/// param name="height">圖片長度/param>
/// returns>圖片/returns>
public static Bitmap CreateVerificationImage(string verificationText, int width, int height)
{
Pen _pen= new Pen(Color.Black);
Font _font = new Font("Arial", 14, FontStyle.Bold);
Brush _brush = null;
Bitmap _bitmap = new Bitmap(width,height);
Graphics _g = Graphics.FromImage(_bitmap);
SizeF _totalSizeF = _g.MeasureString(verificationText,_font);
SizeF _curCharSizeF;
PointF _startPointF = new PointF((width-_totalSizeF.Width)/2,(height-_totalSizeF.Height)/2);
//隨機(jī)數(shù)產(chǎn)生器
Random _random =new Random();
_g.Clear(Color.White);
for(int i=0;iverificationText.Length;i++)
{
_brush = new LinearGradientBrush(new Point(0,0),new Point(1,1),Color.FromArgb(_random.Next(255),_random.Next(255),_random.Next(255)),Color.FromArgb(_random.Next(255),_random.Next(255),_random.Next(255)));
_g.DrawString(verificationText[i].ToString(),_font,_brush,_startPointF);
_curCharSizeF = _g.MeasureString(verificationText[i].ToString(),_font);
_startPointF.X+= _curCharSizeF.Width;
}
_g.Dispose();
return _bitmap;
}
User控制器action中保存驗證碼并返回圖片
首先添加User控制器,在Member區(qū)域中添加控制器UserController。在控制器中寫一個VerificationCode方法。過程是:在方法中我們先創(chuàng)建6位驗證碼字符串->使用CreateVerificationImage創(chuàng)建驗證碼圖片->把圖片寫入OutputStream中->把驗證碼字符串寫入TempData中。
保存在TempData中和Session中的區(qū)別:TempData只傳遞一次,也就是傳遞到下一個action后,action代碼執(zhí)行完畢就會銷毀,Session會持續(xù)保存,所以驗證碼用TempData比較合適。
/// summary>
/// 驗證碼
/// /summary>
/// returns>/returns>
public ActionResult VerificationCode()
{
string verificationCode = Security.CreateVerificationText(6);
Bitmap _img = Security.CreateVerificationImage(verificationCode, 160, 30);
_img.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
TempData["VerificationCode"] = verificationCode.ToUpper();
return null;
}
我們看看生成圖驗證碼效果:
2、Sha256加密
在COmmon項目的Security類中添加靜態(tài)方法Sha256(string plainText)
/// summary>
/// 256位散列加密
/// /summary>
/// param name="plainText">明文/param>
/// returns>密文/returns>
public static string Sha256(string plainText)
{
SHA256Managed _sha256 = new SHA256Managed();
byte[] _cipherText = _sha256.ComputeHash(Encoding.Default.GetBytes(plainText));
return Convert.ToBase64String(_cipherText);
}
四、注冊
在Ninesky.Web.Areas.Member.Models中添加注冊視圖模型
using System.ComponentModel.DataAnnotations;
namespace Ninesky.Web.Areas.Member.Models
{
public class RegisterViewModel
{
/// summary>
/// 用戶名
/// /summary>
[Required(ErrorMessage = "必填")]
[StringLength(20, MinimumLength = 4, ErrorMessage = "{2}到{1}個字符")]
[Display(Name = "用戶名")]
public string UserName { get; set; }
/// summary>
/// 顯示名
/// /summary>
[Required(ErrorMessage = "必填")]
[StringLength(20, MinimumLength = 2, ErrorMessage = "{2}到{1}個字符")]
[Display(Name = "顯示名")]
public string DisplayName { get; set; }
/// summary>
/// 密碼
/// /summary>
[Required(ErrorMessage = "必填")]
[Display(Name = "密碼")]
[StringLength(20,MinimumLength=6,ErrorMessage="{2}到{1}個字符")]
[DataType(DataType.Password)]
public string Password { get; set; }
/// summary>
/// 確認(rèn)密碼
/// /summary>
[Required(ErrorMessage = "必填")]
[Compare("Password", ErrorMessage = "兩次輸入的密碼不一致")]
[Display(Name = "確認(rèn)密碼")]
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }
/// summary>
/// 郵箱
/// /summary>
[Required(ErrorMessage = "必填")]
[Display(Name = "郵箱")]
[DataType(DataType.EmailAddress,ErrorMessage="Email格式不正確")]
public string Email { get; set; }
/// summary>
/// 驗證碼
/// /summary>
[Required(ErrorMessage = "必填")]
[StringLength(6, MinimumLength = 6, ErrorMessage = "驗證碼不正確")]
[Display(Name = "驗證碼")]
public string VerificationCode { get; set; }
}
}
在UserController中添加Register() action ,并返回直接返回強(qiáng)類型(RegisterViewModel)視圖
/// summary>
/// 注冊
/// /summary>
/// returns>/returns>
public ActionResult Register()
{
return View();
}
視圖
@model Ninesky.Web.Areas.Member.Models.RegisterViewModel
@{
ViewBag.Title = "注冊";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
div class="form-horizontal">
h4>用戶注冊/h4>
hr />
@Html.ValidationSummary(true)
div class="form-group">
@Html.LabelFor(model => model.UserName, new { @class = "control-label col-md-2" })
div class="col-md-10">
@Html.EditorFor(model => model.UserName)
@Html.ValidationMessageFor(model => model.UserName)
/div>
/div>
div class="form-group">
@Html.LabelFor(model => model.DisplayName, new { @class = "control-label col-md-2" })
div class="col-md-10">
@Html.EditorFor(model => model.DisplayName)
@Html.ValidationMessageFor(model => model.DisplayName)
/div>
/div>
div class="form-group">
@Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" })
div class="col-md-10">
@Html.EditorFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password)
/div>
/div>
div class="form-group">
@Html.LabelFor(model => model.ConfirmPassword, new { @class = "control-label col-md-2" })
div class="col-md-10">
@Html.EditorFor(model => model.ConfirmPassword)
@Html.ValidationMessageFor(model => model.ConfirmPassword)
/div>
/div>
div class="form-group">
@Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" })
div class="col-md-10">
@Html.EditorFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
/div>
/div>
div class="form-group">
@Html.LabelFor(model => model.VerificationCode, new { @class = "control-label col-md-2" })
div class="col-md-10">
@Html.EditorFor(model => model.VerificationCode)
img id="verificationcode" title="點(diǎn)擊刷新" src="@Url.Action("VerificationCode")" style="cursor:pointer" />
@Html.ValidationMessageFor(model => model.VerificationCode)
/div>
/div>
div class="checkbox">
input type="checkbox" checked="checked" required />我同意 a href="#">《用戶注冊協(xié)議》/a>
/div>
div class="form-group">
div class="col-md-offset-2 col-md-10">
input type="submit" value="注冊" class="btn btn-default" />
/div>
/div>
/div>
}
script type="text/javascript">
$("#verificationcode").click(function () {
$("#verificationcode").attr("src", "@Url.Action("VerificationCode")?" + new Date());
})
/script>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
再在用戶控制器中添加public ActionResult Register(RegisterViewModel register)用來處理用戶提交的注冊數(shù)據(jù)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterViewModel register)
{
if (TempData["VerificationCode"] == null || TempData["VerificationCode"].ToString() != register.VerificationCode.ToUpper())
{
ModelState.AddModelError("VerificationCode", "驗證碼不正確");
return View(register);
}
if(ModelState.IsValid)
{
if (userService.Exist(register.UserName)) ModelState.AddModelError("UserName", "用戶名已存在");
else
{
User _user = new User()
{
UserName = register.UserName,
//默認(rèn)用戶組代碼寫這里
DisplayName = register.DisplayName,
Password = Security.Sha256(register.Password),
//郵箱驗證與郵箱唯一性問題
Email = register.Email,
//用戶狀態(tài)問題
Status = 0,
RegistrationTime = System.DateTime.Now
};
_user = userService.Add(_user);
if (_user.UserID > 0)
{
return Content("注冊成功!");
//AuthenticationManager.SignIn();
}
else { ModelState.AddModelError("", "注冊失?。?); }
}
}
return View(register);
}
代碼中很多根用戶設(shè)置相關(guān)的內(nèi)容先不考慮,等做到用戶設(shè)置時在會后來修改。注冊失敗時返回視圖并顯示錯誤;成功時返回視圖注冊成功,等下次做用戶登錄時可以讓用戶注冊完畢直接進(jìn)行登錄??纯葱Ч?/p>
點(diǎn)擊注冊,注冊成功。
一個簡單的用戶注冊完成了,主要有驗證碼、sha256加密、注冊視圖模型、驗證用戶提交數(shù)據(jù)并保存等步驟。后面就是用戶注冊,注冊會用到ClaimsIdentity和HttpContext.GetOwinContext().Authentication.SignIn();
本文已被整理到了《ASP.NET MVC網(wǎng)站開發(fā)教程》,歡迎大家學(xué)習(xí)閱讀,更多內(nèi)容還可以參考ASP.NET MVC5網(wǎng)站開發(fā)專題學(xué)習(xí)。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:- ASP.NET MVC5網(wǎng)站開發(fā)用戶登錄、注銷(五)
- PHP MVC模式在網(wǎng)站架構(gòu)中的實(shí)現(xiàn)分析
- ASP.NET MVC5 網(wǎng)站開發(fā)框架模型、數(shù)據(jù)存儲、業(yè)務(wù)邏輯(三)
- MVC4 網(wǎng)站發(fā)布(整理+部分問題收集和解決方案)
- CodeIgniter php mvc框架 中國網(wǎng)站
- PHP發(fā)明人談MVC和網(wǎng)站設(shè)計架構(gòu) 貌似他不支持php用mvc
- ASP.NET MVC5網(wǎng)站開發(fā)項目框架(二)
- ASP.NET MVC5網(wǎng)站開發(fā)顯示文章列表(九)
- ASP.NET MVC5網(wǎng)站開發(fā)添加文章(八)
- 一步步打造簡單的MVC電商網(wǎng)站BooksStore(1)