三、Asp.Net MVC4.0開發CMS系統案例之用戶登錄模塊開發

    本次開發是將三層架構與MVC結合一起來,我們看下面一個系統結構:

    View ->Contraller->Model->BLL->DAL->SQLSERVER

             |        |        |

             ----------->Extensions----->FrameWork

             |

             __>Common


    Extensions包括擴展類功能,例如控件的再重新,權限的重新驗證等。Common是一些公共性功能。


    第一步:創建用戶登錄模型,可以與註冊模型類(SysComUerRegister),用戶模型(SysComUser)寫入同一個文件中。

    /// <summary>
    /// 用戶登錄
    /// </summary>
    ///子類並不映射到任何數據庫,加上一個不映射的屬性[NotMapped]
    [NotMapped]
    public class SysComUserLogin
    {

        [Display(Name = "登錄名", Description = "4-20個字符")]
        [Required(ErrorMessage = "×")]
        [StringLength(20, MinimumLength = 4, ErrorMessage = "×")]
        public string LoginName { get; set; }

        [Display(Name = "登錄密碼", Description = "6-20個字符")]
        [Required(ErrorMessage = "×")]
        [StringLength(20, MinimumLength = 6, ErrorMessage = "×")]
        [DataType(DataType.Password)]
        public new string Password { get; set; }

        [Display(Name = "驗證碼", Description = "請輸入驗證碼!")]
        [Required(ErrorMessage = "×")]
        [StringLength(4, MinimumLength = 4, ErrorMessage = "×")]
        public string VerificationCode { get; set; }
    }

    第二步:控制器Conrallers方法的實現。這裏我們考慮有三個:一個是默認的登錄頁面方法,一個是HTTPPOST提交登錄數據的方法,還有一個註銷的方法。如下:

        /// <summary>
        /// 用戶登錄頁面
        /// </summary>
        /// <returns></returns>
        public ActionResult UserLogin()
        {
            return View();
        }

        /// <summary>
        /// 用戶提交登錄
        /// </summary>
        /// <param name="userLogin"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult UserLogin(SysComUserLogin userLogin)
        {
            //說明:因爲在Models中,已經實現用戶名和密碼驗證規則,因爲這裏不需要重複判斷了,但驗證碼除外,因爲它是保存Session緩存中.
            if (String.IsNullOrEmpty(Session["VerificationCode"].ToString()))
            {
                ModelState.AddModelError("VerificationCode", "×");
                return View();
            }
            else if (Session["VerificationCode"].ToString() != userLogin.VerificationCode)
            {
                ModelState.AddModelError("VerificationCode", "×");
                return View();
            }
            else
            {
                if (userRpy.Authentication(userLogin.LoginName,userLogin.Password) == 0)
                {
                    HttpCookie _cookie = new HttpCookie("user");
                    _cookie.Values.Add("loginname", userLogin.LoginName);
                    _cookie.Values.Add("password", userLogin.Password);
                    Response.Cookies.Add(_cookie);
                    ModelState.AddModelError("Message", "登陸成功!!");
                    return View();
                }
                else
                {
                    ModelState.AddModelError("Message", "登陸失敗!");
                    return View();

                }
            }

        }


        /// <summary>
        /// 註銷登錄信息
        /// </summary>
        /// <returns>URL</returns>
        public ActionResult UserLoginOut()
        {
            HttpCookie _cookie = HttpContext.Request.Cookies["user"];
            if (_cookie != null)
            {
                //失效時間
                _cookie.Expires = DateTime.Now.AddHours(-1);
                Response.Cookies.Add(_cookie);
            }
            return View();
        }

    這裏面用到一個Authentiction()用戶身份驗證方法,所以需要在BLL業務層實現。


    第三步:BLL業務邏輯層方法實現

        /// <summary>
        /// 用戶登錄身份驗證
        /// </summary>
        /// <param name="loginName">登錄名</param>
        /// <param name="password">密碼</param>
        /// <returns>0:登錄成功;1:登錄名不存在;2:密碼錯誤</returns>
        public int Authentication(string loginName, string password)
        {
            var _user = HillstoneContext.SysComUser.SingleOrDefault(u=>u.LoginName==loginName);
            if (_user == null) { return 1; }
            if (_user.Password != password) { return 2; }
            return 0;
        }

    第四步:所有涉及的東西都寫完了,下面就是實現VIEW了。如下:

@model Hillstone.Models.SysComUserLogin

@{
    ViewBag.Title = "用戶登錄";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>UserLogin</h2>

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>SysComUserLogin</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.LoginName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LoginName)
            @Html.ValidationMessageFor(model => model.LoginName)
            @Html.DisplayDescriptionFor(model=>model.LoginName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Password)
        </div>
        <div class="editor-field">
            @Html.PasswordFor(model => model.Password)
            @Html.DisplayDescriptionFor(model => model.LoginName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.VerificationCode)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(model => model.VerificationCode)
            @Html.ValidationMessageFor(model => model.VerificationCode)
             <img id="verificationcode" alt="" src="@Url.Action("VerificationCode", "SysComUser")" /> 
             <a id="trydifferent" style="cursor: pointer">換一張</a> 
        </div>

        <p>
            <input type="submit" value="Save" />@Html.ValidationMessage("Message")
        </p>
    </fieldset>
}

<div>

    @Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript" >
    function VerificationChange() {
        $("#verificationcode").attr("src", "/SysComUser/VerificationCode?" + new Date());
    }
   
</script>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

    第五部:其他考慮,我們登錄後,每次頁面跳轉或者刷新,需要確認身份是否失效或者有效,那麼問題就來了,是不是在所有的頁面請求Contraller時候都要調用BLL中的Authencation()方法來驗證呢?其實系統默認有驗證機制類庫,我們可以重新寫這個接口,使用起來更加簡潔方面,提交我們的開發效率。所以我做個擴展,在Extensions文件夾中新建UserAuthorizeAttribute.cs類。如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Hillstone.BLL;

namespace System.Web.Mvc
{
    /// <summary>
    /// 用戶權限驗證
    /// </summary>
    public class UserAuthorizeAttribute:AuthorizeAttribute
    {
        /// <summary>
        ///  核心【驗證用戶是否登錄】以後只要在需要登錄後才能操作的Action或Controller上加[UserAuthorize]就可實現驗證是否已經登錄了。
        /// </summary>
        /// <param name="httpContext">HTTP請求</param>
        /// <returns>布爾值:True or False</returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext.Request.Cookies["user"] == null) return false;
            HttpCookie _cookie = httpContext.Request.Cookies["user"];

            string _loginName = _cookie["loginname"];
            string _password = _cookie["password"];

            httpContext.Response.Write("登錄名:" + _loginName);

            if (string.IsNullOrEmpty(_loginName) || string.IsNullOrEmpty(_password)) return false;

            SysComUserRepository userRsy = new SysComUserRepository();
            if (userRsy.Authentication(_loginName, _password) == 0) return true;
            else return false;
        }
    }
}

   繼承AuthorizeAttribute類庫,這裏做AuthorizeCore方法重寫,裏面調用BLL中的Authencation()登錄驗證方法。 以後所有需要登錄之後才能操作的Contraller中,在Action之前加上[UserAuthorize]即可。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章