using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; namespace MvcTest.Models { public partial class Member { public int Id { get; set; } [DisplayName("会员账号")] [Required(ErrorMessage = "请输入 Email 地址")] [Description("我们直接以 Email 当成会员的登录账号")] [MaxLength(250, ErrorMessage = "Email地址长度无法超过250个字符")] [DataType(DataType.EmailAddress)] [Remote("CheckDup", "Member", HttpMethod = "POST", ErrorMessage = "您输入的 Email 已经有人注册过了!")] public string Email { get; set; } [DisplayName("会员密码")] [Required(ErrorMessage = "请输入密码")] [MaxLength(40, ErrorMessage = "请输入密码")] [DataType(DataType.Password)] public string Password { get; set; } [DisplayName("中文姓名")] [Required(ErrorMessage = "请输入中文姓名")] [MaxLength(5, ErrorMessage = "中文姓名不可超过5个字")] [Description("暂不考虑外国人用英文注册会员的情况")] public string Username { get; set; } [DisplayName("会员昵称")] [Required(ErrorMessage = "请输入会员昵称")] [MaxLength(10, ErrorMessage = "会员昵称请勿输入超过10个字")] public string Nickname { get; set; } [DisplayName("会员注册时间")] public DateTime RegisterOn { get; set; } [DisplayName("会员启用认证码")] [MaxLength(36)] [Description("当 AuthCode 等于 null 则代表此会员已经通过Email有效性验证")] public string AuthCode { get; set; } } }
using System.ComponentModel; using System.ComponentModel.DataAnnotations; namespace MvcTest.Models { public class MemberLoginViewModel { [DisplayName("会员账号")] [DataType(DataType.EmailAddress, ErrorMessage = "请输入您的 Email 地址")] [Required(ErrorMessage = "请输入{0}")] public string email { get; set; } [DisplayName("会员密码")] [DataType(DataType.Password)] [Required(ErrorMessage = "请输入{0}")] public string password { get; set; } } }
控制器部分
using MvcTest.Models; using System; using System.Collections.Generic; using System.Linq; using System.Net.Mail; using System.Web; using System.Web.Mvc; using System.Web.Security; namespace MvcShopping.Controllers { public class MemberController : Controller { protected testContext db = new testContext(); // 会员注册页面 public ActionResult Register() { return View(); } // 写入会员资料 [HttpPost] public ActionResult Register([Bind(Exclude="RegisterOn,AuthCode")] Member member) { // 检查会员是否存在 var chk_member = db.Members.Where(p => p.Email == member.Email).FirstOrDefault(); if (chk_member != null) { ModelState.AddModelError("Email", "您输入的 Email 已经有人注册过了!"); } if (ModelState.IsValid) { // 会员注册时间 member.RegisterOn = DateTime.Now; // 会员验证码,采用 Guid 当成验证内容,避免有会员使用到重复的验证码 member.AuthCode = Guid.NewGuid().ToString(); db.Members.Add(member); db.SaveChanges(); return RedirectToAction("Login", "Member"); } else { return View(); } } private void SendAuthCodeToMember(Member member) { // 准备发送邮件内容 string mailBody = System.IO.File.ReadAllText(Server.MapPath("~/App_Data/MemberRegisterEMailTemplate.htm")); mailBody = mailBody.Replace("{{Name}}", member.Username); mailBody = mailBody.Replace("{{RegisterOn}}", member.RegisterOn.ToString("F")); var auth_url = new UriBuilder(Request.Url) { Path = Url.Action("ValidateRegister", new { id = member.AuthCode }), Query = "" }; mailBody = mailBody.Replace("{{AUTH_URL}}", auth_url.ToString()); // 发送邮件给会员 try { SmtpClient SmtpServer = new SmtpClient("smtp.126.com"); //SmtpServer.Port = 587; SmtpServer.Credentials = new System.Net.NetworkCredential("[email protected]", "password"); SmtpServer.EnableSsl = true; MailMessage mail = new MailMessage(); mail.From = new MailAddress("[email protected]"); mail.To.Add(member.Email); mail.Subject = "会员注册确认信"; mail.Body = mailBody; mail.IsBodyHtml = true; SmtpServer.Send(mail); } catch (Exception ex) { throw ex; // 发送邮件寄送失败,需记录到数据库备查,以免有会员无法登录 } } public ActionResult ValidateRegister(string id) { if (String.IsNullOrEmpty(id)) return HttpNotFound(); var member = db.Members.Where(p => p.AuthCode == id).FirstOrDefault(); if (member != null) { TempData["LastTempMessage"] = "会员验证成功,您现在可以登入网站了!"; //邮件点击验证成功后要将 member.AuthCode 的内容清空 member.AuthCode = null; db.SaveChanges(); } else { TempData["LastTempMessage"] = "查无此会员验证码,您可能已经验证过了!"; } return RedirectToAction("Login", "Member"); } // 显示会员登录页面 public ActionResult Login(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } // 执行会员登录 [HttpPost] public ActionResult Login(string email, string password, string returnUrl) { if (ValidateUser(email, password)) { FormsAuthentication.SetAuthCookie(email, false); if (String.IsNullOrEmpty(returnUrl)) { return RedirectToAction("Index", "Home"); } else { return Redirect(returnUrl); } } return View(); } private bool ValidateUser(string email, string password) { var hash_pw = password; var member = (from p in db.Members where p.Email == email && p.Password == hash_pw select p).FirstOrDefault(); // 如果 member 模型 null 则代表输入的用户名和密码正确 if (member != null) { if (member.AuthCode == null) { return true; } else { ModelState.AddModelError("", "您尚未通过会员验证,请查收邮件点击会员验证链接!"); return false; } } else { ModelState.AddModelError("", "您输入的用户名或密码错误!"); return false; } } // 执行会员注销登录 public ActionResult Logout() { // 清除 Cookies FormsAuthentication.SignOut(); // 清除所有曾经写入过的 Session 资料 Session.Clear(); return RedirectToAction("Index", "Home"); } [HttpPost] public ActionResult CheckDup(string Email) { var member = db.Members.Where(p => p.Email == Email).FirstOrDefault(); if (member != null) return Json(false); else return Json(true); } } }视图部分
@model MvcTest.Models.MemberLoginViewModel <h2>会员登录</h2> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>请输入你的用户名和密码</legend> <div class="editor-label"> @Html.LabelFor(model => model.email) </div> <div class="editor-field"> @*@Html.EditorFor(model => model.email)*@ @Html.TextBoxFor(model => model.email, new { data_val_email = "请输入 Email 地址" }) @Html.ValidationMessageFor(model => model.email) </div> <div class="editor-label"> @Html.LabelFor(model => model.password) </div> <div class="editor-field"> @Html.EditorFor(model => model.password) @Html.ValidationMessageFor(model => model.password) </div> <p> <input type="submit" value="登录" /> </p> </fieldset> } <div> @Html.ActionLink("注册账号", "Register", "Member") </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") @if (TempData["LastTempMessage"] != null) { <script> alert('@HttpUtility.JavaScriptStringEncode(Convert.ToString(TempData["LastTempMessage"]))'); </script> } }
@model MvcTest.Models.Member <h2>会员注册</h2> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>请输入会员注册资料</legend> <div class="editor-label"> @Html.LabelFor(model => model.Email) </div> <div class="editor-field"> @Html.EditorFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email) </div> <div class="editor-label"> @Html.LabelFor(model => model.Password) </div> <div class="editor-field"> @Html.EditorFor(model => model.Password) @Html.ValidationMessageFor(model => model.Password) </div> <div class="editor-label"> @Html.LabelFor(model => model.Username) </div> <div class="editor-field"> @Html.EditorFor(model => model.Username) @Html.ValidationMessageFor(model => model.Username) </div> <div class="editor-label"> @Html.LabelFor(model => model.Nickname) </div> <div class="editor-field"> @Html.EditorFor(model => model.Nickname) @Html.ValidationMessageFor(model => model.Nickname) </div> <p> <input type="submit" value="注册" /> </p> </fieldset> } @section Scripts { @Scripts.Render("~/bundles/jqueryval") }确认邮件模板
<!DOCTYPE html> <html> <body> <h1>会员注册确认信</h1> <p>亲爱的 {{Name}} 您好:</p> <p> 由于您在 {{RegisterOn}} 注册成为本站会员,为了完成会员注册程序,请您点击以下链接用以确认您的Email地址是有效的: <br /> <a href="{{AUTH_URL}}" target="_blank">{{AUTH_URL}}</a> </p> </body> </html>