EF6 CodeFirst + Repository + Ninject + MVC4 + EasyUI practice (9), ef6codefirst
Preface
- In this article, we will complete the system permission setting function and dynamically load menus after logging on to the system by users of different roles. Note: This example only applies to menu-level permissions. If you need more complex system permission settings, you can extend the permissions to button-level or attribute-level permissions.
- User Login is implemented using Form authentication, which effectively prevents unauthorized users or page links from causing insecure operations on the system.
Permission setting module
- The role list and menu list are selected on the page, that is, select the menus that can be operated after selecting a role, so that users with a role have the permission to operate these menus. The interface settings are as follows:
- The roleID and menuID selected on the interface are concatenated using strings. In the controller, the received object type is used, and the passed value can be obtained after conversion. The reference code for permission settings is as follows:
Public bool SetPermit (object RoleID, object MenuIDs) {try {string [] roleArr = RoleID as string []; long roleID = Convert. toInt64 (roleArr [0]. toString (); S_Role role = context. s_Roles.Where (x => x. ID. equals (roleID )). firstOrDefault (); // gets the role. s_Menus = new List <S_Menu> (); // Delete the data List of the previously set roleID <S_Menu> listdate = context. s_Roles.Where (x => x. ID. equals (roleID )). firstOrDefault (). s_Menus.ToList (); foreach (var item in listdate) {role. s_Menus.Remove (item);} // write existing data string [] MenuArr = MenuIDs as string []; string [] MenuArrString = MenuArr [0]. toString (). trimEnd (','). split (','). toArray (); List <long> arr = new List <long> (); foreach (var item in MenuArrString) {arr. add (Convert. toInt64 (item);} // must be converted to a list set. Otherwise, "an existing DataReader associated with this Command is displayed, you must first disable "Error List <S_Menu> query = (from m in context. s_Menus where arr. contains (m. ID) select m ). toList (); foreach (S_Menu menu in query) {role. s_Menus.Add (menu); menu. s_Roles = new List <S_Role> (); menu. s_Roles.Add (role);} // EF enables transaction commit context by default. saveChanges (); return true;} catch {return false ;}}
- To reflect the menu permissions that the role has after the permission is set successfully, we need to append the click event to the easyui-datagrid of the role and asynchronously load the menu permissions that the role has. Easyui-Datagrid itself has a very useful data method unselectAll (deselect all rows on the current page ). However, it must be placed before the selected menu permission. The reference code is as follows:
$ ('# Dg '). datagrid ({onClickRow: function (index, data) {var row = $ ('# dg '). datagrid ('getselected'); if (row) {var RoleID = row. ID; $. ajax ({url: '/System/GetPermit', type: 'post', data: {RoleID: RoleID}, success: function (data) {$ ('# dgMenu '). treegrid ('unselectall'); // reload $ ('# dgMenu '). treegrid ({onLoadSuccess: function (dataaa) {$. each (data, function (index, item) {$ ('# dgMenu '). treegrid ('selectrow', item); // select the set permission });}});}})}}});
System logon users get menu operation Permissions
- After the permission setting module is complete, users of different roles can log on to the system and perform different menu permissions. Because the menu uses easyui-tree to bind data, we need to define a data model that complies with the easyui-tree attribute, in this way, the json data format recognized by easyui-tree can be serialized. (This is the same as the previous easyui-treegrid method ). The reference code is as follows:
Public class mod_S_RoleMenuTree {public long id {get; set ;}// node ID public string text {get; set ;}// public string iconCls {get; set;} public string url {get; set;} public int treelevel {get; set;} // node status, which has two values: 'Open' or 'closed ', the default value is 'open '. if it is set to 'closed ', it indicates that this node has subnodes. Otherwise, this node is the public string state {get; set;} public List <mod_S_RoleMenuTree> children {get; set ;} // subnode set}
- In MainController, we can obtain the menu permissions of this User Role Based on the login user name. The menu in this example is set to only two levels, so no recursion is performed. If you need a multi-level menu, you can refer to the previous article to change the following method to a recursive method. The reference code is as follows:
public ActionResult GetRoleMenus() { string strUser = System.Web.HttpContext.Current.User.Identity.Name; List<S_Menu> listData = IS_Role.GetRoleMenus(strUser); var listDataParent = listData.Where(x => x.PID.Equals(null)).OrderBy(x => x.SerialNO); List<mod_S_RoleMenuTree> DataModel = new List<mod_S_RoleMenuTree>(); foreach (var item in listDataParent) { mod_S_RoleMenuTree model = new mod_S_RoleMenuTree(); model.id = item.ID; model.text = item.MenuName; model.iconCls = item.Icon; model.state = "open"; model.url = item.Link; model.treelevel = item.Level; model.children = new List<mod_S_RoleMenuTree>(); var children = listData.Where(x => x.PID.Equals(item.ID)).OrderBy(x => x.SerialNO); foreach (var childitem in children) { mod_S_RoleMenuTree childmodel = new mod_S_RoleMenuTree(); childmodel.id = childitem.ID; childmodel.text = childitem.MenuName; childmodel.iconCls = childitem.Icon; childmodel.state = "open"; childmodel.url = childitem.Link; model.treelevel = childitem.Level; model.children.Add(childmodel); } DataModel.Add(model); } return Json(DataModel, JsonRequestBehavior.AllowGet); }
- Then, replace the code for obtaining menu data in Index view of MainController with the following code, so that we can dynamically read the menu from the database, rather than directly reading the json file.
<ul class="easyui-tree" id="txt" data-options="url:'/Main/GetRoleMenus',method:'get',animate:true,lines:true"></ul>
Logon
- We have set up an account admin \ Jack for the system. admin has the administrator role and Jack has the Operator role. Therefore, the menus displayed after two users log on are different. The User Logon code is as follows:
[HttpPost] public ActionResult Login(mod_Account model) { if (null != model){ if (IS_User.Login(model.UserName, DESEncrypt.Encrypt(model.UserPwd))){ System.Web.Security.FormsAuthentication.SetAuthCookie(model.UserName, false); return RedirectToAction("Index", "Main"); } else{ return View(); } } else{ return View(); } }
- Because Form authentication is used, we also need to modify the code in the configuration file:
<authentication mode="Forms"> <forms loginUrl="/Account/Login" timeout="2880" protection="All" /> </authentication> <authorization> <deny users="?"/> </authorization>
- When you exit, You need to log out of the authenticated user by referring to the following code:
public ActionResult LoginOut() { System.Web.Security.FormsAuthentication.SignOut(); return RedirectToAction("Login", "Account"); }
- At this point, we have completed the basic functional modules of this example. The source code of this example has been placed on the network disk,Click here to download. The following figure shows the logon page for different users: