一、前言:
1、再看這篇文章的時候,您是否已經完成前兩篇介紹的文章里的功能了?(Tabs頁的添加,Tabs頁右鍵的關閉,主題的更換)
2、今天來說說登錄窗口吧,看截圖:是不是在進入的時候左邊的菜單欄和中間的Tabs頁沒有內容(安全起見,必須得這樣,只有登錄成功后頁面才能顯示)。
而且還得是后面的內容是不能選擇的,用過Jquery-EasyUI的朋友都知道,.dialog中有個Modal設置為True就行。
二、登錄窗口功能如何實現?
1、還記的第二篇中說到MVC3中Shared文件夾下邊的_houai.cshtml中有個@RenderBody,這個是布局頁中必須得有一個,說白了就是一個“坑”,放內容頁的地方。
2、所以在進入系統后台的時候,我把這個登錄窗口就嵌套在這個布局頁當中。文件位置如下:
3、在Index中記得引用布局頁:Layout = "~/Areas/houtai/Views/Shared/_houtai.cshtml";
4、Jquery-EasyUI中的Dialog本身也是個DIV,怎么讓他渲染成一個Dialog,有兩種方式,我用的是寫Jquery的方式。
(1)剛進入頁面,先讓輸入用戶名的地方進行設置焦點。
(2)AJAX的方式去驗證用戶名和密碼。如果登錄成功后,leftTreeLimits()方法判斷此用戶擁有什么樣的權限!該顯示哪些內容!這時Dialog窗口應該得關閉。
<script type="text/javascript"> var dialogID; $(function () { $("#name1").focus(); dialogID = $("#dlg").dialog({ closable: false, modal: true, buttons: [ { text: "登錄", handler: function () { $.post( "/Account/LogIn", { "UserName":$("#name1").val(), "password":$("#pwdd").val(), }, function(d) { if (d=="yes") {
//菜單項判斷此用戶所擁有的功能! leftTreeLimits(); $("#dlg").dialog('close'); $.messager.show({msg:"登錄成功!",title:"提示"}); $("#bodyColor").css("display", ""); $("#bodyColor1").css("display", ""); } else if (d=="no") { $.messager.alert("提示","用戶名和密碼錯誤!"); return;
} } ); } }] }); }); </script>
(3)、body部分當然得有個表單,這個DIV用上面Jquery的方式渲染成一個Dialog,Controller部分,只返回一個View()就行。
@using (Html.BeginForm("", "",FormMethod.Post,new{id="Login"})) { <div id="dlg" title="登錄" style="width: 400px; height: 200px; padding: 10px"> <table id="list" style="background-color:#e5e1e5;"> <tr><td>用戶名:</td><td><input id="name1" name="name" type="text" class="easyui-validatebox" value="tianxin" required="true" missingMessage="請輸入用戶名" /></td></tr> <tr><td>密碼:</td><td><input id="pwdd" name="password" type="password" class="easyui-validatebox" required="true" width="10px" missingMessage="請輸入密碼"/></td></tr> </table> </div> }
(4)、通過第(2)個Jquery的代碼很容易看出來進入的是哪個頁面去判斷的用戶名和密碼,/Account/Login。在這個Action里也得做這幾個功能:
1、判斷用戶名和密碼是否正確。
2、窗體的身份驗證和登錄成功后加入到Cookie中。
3、Model類使用的就是Account中的默認的LogOnModel。
4、FormsAuthenticationTicket第六個重載(user.ID),可以保存這個數據,在Global.asax.cs取到這個數據之后還有驚喜!!(稍后寫出來)
private static readonly string UserNameSessionKey = "Name"; public ActionResult LogIn() { HttpCookie c = HttpContext.Request.Cookies[UserNameSessionKey]; LogOnModel model = new LogOnModel { UserName = c != null ? c.Value : "" }; return View(model); } [HttpPost] public ActionResult LogIn(LogOnModel model, string returnUrl) { if (model == null) { var m = TempData["User"] as LogOnModel; if (m != null) { model = m; } } if (ModelState.IsValid == false) return View(model); var user = userBLL.GetByNameAndPassword(model.UserName.Trim(), model.Password.Trim()); if (user==null) { return Content("no"); } { HttpCookie c = new HttpCookie(UserNameSessionKey,model.UserName); HttpContext.Response.Cookies.Add(c); } //窗體票據的驗證 FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket( 1, user.UserName, DateTime.Now, DateTime.Now.AddMinutes(20), false, user.ID.ToString(), "/" ); HttpCookie cookie = new HttpCookie( FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authTicket) ); Response.Cookies.Add(cookie); if (!String.IsNullOrEmpty(returnUrl)) { if (returnUrl[0] != '/') returnUrl = "/" + returnUrl; return Redirect(returnUrl); } if (user != null) { return Content("yes"); } else return Redirect("~/houtai"); }
5、在Global.asax.cs中如何取到前面的那個值??給 MvcApplication 增加構造函數,在其中增加 AuthorizeRequest 事件的處理函數。
public MvcApplication()
{
AuthenticateRequest += new EventHandler(MvcApplication_AuthenticateRequest);
}
void MvcApplication_AuthenticateRequest(object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
int userID = int.Parse(authTicket.UserData);
var userPrincipal = new Principal(userID, new GenericIdentity(authTicket.Name), new string[] { });
Context.User = userPrincipal;
}
}
6、上面這段代碼有沒有看到Pricipal,表示一般用戶,以后方便對Controller寫個擴展方法,只要在任何的Controller中,使用類似這樣:this.User(),就可以獲得登陸后的用戶,記得不要保存在Session中,將用戶保存在 Session 中是一種非常不好的做法。下面就實現Principal.
//實現GenericPrincipal,表示一般用戶 public class Principal : GenericPrincipal { public int ID { get; set; } public Principal(int id, IIdentity identity, string[] roles) : base(identity, roles) { this.ID = id; } }
7、上面說到擴展方法,來寫一個吧,對Controller進行擴展。使用了NHibernate;NHibernate.Linq(Nhibernate中使用Linq查詢的方式),擴展方法必須靜態的,如果要用的話必須在Web.Config下添加命名空間,或者使用這種“懶”的方式,Using System.Web.MVC。這樣的話在任何一個Controller中都可以使用var User=this.User();得到登錄的用戶的信息了。
public static Users User(this Controller controller) { var principal = controller.User as MvcApplication.Principal; if (principal == null) return null; return GetCurrentSession().Linq<User>() .Where(u => u.ID == principal.ID) .FirstOrDefault(); }
5、上面的登錄功能的內容引申的知識點有點多了,個人認為還是詳細點好,對於初學者來說看的更清晰一點。驗證用戶和獲得用戶就告一段落吧,接下說說,登錄成功之后判斷左邊的菜單項,該顯示哪些菜單,這個主要是判斷他具有哪些權限?思路:(1)判斷完權限之后,返回擁有權限的JSon數據的名稱(2)然后和所有的權限(初始化時,所有的權限都在左邊菜單欄)進行對比(3)返回的數據如果沒有的話,就使用Jquery進行Remove或者Hide掉。剩下的不就是他所擁有的權限了嗎。這是我的一種想法。如果還有其他的想法的話,請朋友們留言,也學習一下。
////TX:用戶所擁有的權限菜單 function leftTreeLimits() { $.post("/houtai/Privilige/PrivigeLimit",{},function(data){ if (data!=null&&data!=undefined) { var node=$(".panel p a"); $.each(data,function(a,b){ for (var i = 0; i < node.length; i++) { if($(node[i]).text()==b) { $(node[i]).parent().remove(); } } }); var parentNo=$("#accordionId .panel"); for (var j = 0; j < parentNo.length; j++) { if ($(parentNo[j]).children("#MenuID").children("p").length==0) { $(parentNo[j]).hide(); } } } }); }
6、上面的JS很清晰,導向了/houtai/Privilige/PrivigeLimit,返回的是JSon數據,然后遍歷他的Name,進行比較。刪除沒有權限的名稱。
//進入系統菜單權限分配 public JsonResult PrivigeLimit() { var user = this.User(); if (user == null) { return Json(null); } return Json(userLimitBll.GetLimits(user.ID)); }
三、總結:登錄功能已經完成,涉及到的知識點挺多的,也說了說思路,說的應該挺清晰的吧。如果對您有幫助,請繼續關注這個系列吧,幫忙點擊右下角“推薦”,讓更多的朋友來共同學習,共同進步!!