【MVC】会员注册/登录,普通验证,会员名是否注册Ajax验证以及会员邮件验证实现原理

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>

你可能感兴趣的:(【MVC】会员注册/登录,普通验证,会员名是否注册Ajax验证以及会员邮件验证实现原理)