تعیین سطح دسترسی کاربران (بصورت جزئی به اجزا سایت) در MVC
پنجشنبه 22 مرداد 1394در این مقاله قصد داریم تعیین سطح دسترسی هر کار بر صورت جداگانه به عناصر صفحات و خود صفحات را به صورت داینامیک و در لحظه اجراآموزش دهیم
برای شروع یک بانک اطلاعاتی به نام Example ایجاد میکنیم
یک جدول برای نگهداری اطلاعات ورود کاربران با نام Users ایجاد میکنیم.
سپس یک جدول با نام Permissions برای نگهداری اطلاعات مربوط به کنترل ها و صفحات میسازیم
در این جدول ستون ParentID برای نگهداری والد این رکورد میباشد
مثلا صفحه کاربران چند زیر مجموعه با عنوان های ثبت کاربر جدید و ویرایش و ... دارد که با این ستون میتوانیم مشخص کنیم که این Permission برای کدام یک از صفحات یا کنترل اصلی می باشد
سپس یک جدول برای نگهداری دسترسی هر کاربر با نام Users_Permissions می سازیم
را بطه این جدول با Users و Permissions را بر قرار میکنیم
اسکریپت ساخت بانک اطلاعاتی به همراه جداول به شرح ذیل است :
ابتدا بانکی با نام User_Permission_DB بسازید و اسکریپت زیر را روی آن اجرا کنید
GO /****** Object: Table [dbo].[Users] Script Date: 06/13/2015 16:09:29 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Users]( [UserID] [int] IDENTITY(1,1) NOT NULL, [UserName] [nvarchar](150) NOT NULL, [Password] [nvarchar](150) NOT NULL, CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ( [UserID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET IDENTITY_INSERT [dbo].[Users] ON INSERT [dbo].[Users] ([UserID], [UserName], [Password]) VALUES (1, N'ایمان مدائنی', N'123') INSERT [dbo].[Users] ([UserID], [UserName], [Password]) VALUES (2, N'برنامه نویسان', N'123') SET IDENTITY_INSERT [dbo].[Users] OFF /****** Object: Table [dbo].[Permissions] Script Date: 06/13/2015 16:09:29 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Permissions]( [PermissionID] [int] IDENTITY(1,1) NOT NULL, [PermissionTitle] [nvarchar](150) NOT NULL, [ParentID] [int] NULL, CONSTRAINT [PK_Permissions] PRIMARY KEY CLUSTERED ( [PermissionID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET IDENTITY_INSERT [dbo].[Permissions] ON INSERT [dbo].[Permissions] ([PermissionID], [PermissionTitle], [ParentID]) VALUES (1, N'پنل مدیریت', NULL) INSERT [dbo].[Permissions] ([PermissionID], [PermissionTitle], [ParentID]) VALUES (2, N'صفحه مدیریت کاربران', NULL) INSERT [dbo].[Permissions] ([PermissionID], [PermissionTitle], [ParentID]) VALUES (3, N'افزودن کاربر جدید', 2) INSERT [dbo].[Permissions] ([PermissionID], [PermissionTitle], [ParentID]) VALUES (4, N'تعیین سطح دسترسی', 2) SET IDENTITY_INSERT [dbo].[Permissions] OFF /****** Object: Table [dbo].[Users_Permissions] Script Date: 06/13/2015 16:09:29 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Users_Permissions]( [UP_ID] [int] IDENTITY(1,1) NOT NULL, [UserID] [int] NOT NULL, [PermissionID] [int] NOT NULL, CONSTRAINT [PK_Users_Permissions] PRIMARY KEY CLUSTERED ( [UP_ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET IDENTITY_INSERT [dbo].[Users_Permissions] ON INSERT [dbo].[Users_Permissions] ([UP_ID], [UserID], [PermissionID]) VALUES (7, 1, 1) INSERT [dbo].[Users_Permissions] ([UP_ID], [UserID], [PermissionID]) VALUES (8, 1, 4) SET IDENTITY_INSERT [dbo].[Users_Permissions] OFF /****** Object: ForeignKey [FK_Users_Permissions_Permissions] Script Date: 06/13/2015 16:09:29 ******/ ALTER TABLE [dbo].[Users_Permissions] WITH CHECK ADD CONSTRAINT [FK_Users_Permissions_Permissions] FOREIGN KEY([PermissionID]) REFERENCES [dbo].[Permissions] ([PermissionID]) GO ALTER TABLE [dbo].[Users_Permissions] CHECK CONSTRAINT [FK_Users_Permissions_Permissions] GO /****** Object: ForeignKey [FK_Users_Permissions_Users] Script Date: 06/13/2015 16:09:29 ******/ ALTER TABLE [dbo].[Users_Permissions] WITH CHECK ADD CONSTRAINT [FK_Users_Permissions_Users] FOREIGN KEY([UserID]) REFERENCES [dbo].[Users] ([UserID]) GO ALTER TABLE [dbo].[Users_Permissions] CHECK CONSTRAINT [FK_Users_Permissions_Users] GO
حالا یک پروژه با نام Permission_MVC ایجاد میکنیم
حال یک Areas به نام AdminManager برای قرار دادن صفحات مدیریت ایجاد میکنیم
حال یک کنترل ،از نوع Users از جنس Controller with views, using Entity Framework MVC 5 ایجاد میکنیم.
حال از برنامه اجرا گرفته و شروع به ثبت داده کنید
حال در این مرحله میخواهیم به با استفاده از TreeView به پیاده سازی سطح دسترسی ها بپردازیم
ابتدا یک کلاس به نام Treelist با متغیر های زیر ایجاد میکنیم
public class Treelist { public int Id { set; get; } public string Name { set; get; } public int? ParentId { get; set; } public int ExtraID { get; set; } public List<Treelist> TreeListItm { get; set; } // مخصوص کندو یو آی هستند public bool HasChildren { get; set; } public bool Checked { get; set; } public string imageUrl { get; set; } }
حال برای استفاده از TreeView یک کلاس به نام TreeClasses ایجاد میکنیم
public class TreeClasses { public Treelist LoadTreeByBindingModel(List<Treelist> _Treelist, int RootID) { Treelist _Treelist_Out = new Treelist(); #region Check Exites One Parentes int CountParent = _Treelist.Where(n => n.Id == RootID).Count(); if (CountParent != 1) { return _Treelist_Out; } #endregion #region FillData _Treelist_Out = _Treelist.Where(n => n.Id == RootID).FirstOrDefault(); //_Treelist_Out .Checked ==>Defult Ast //_Treelist_Out.Id ==>Defult Ast //_Treelist_Out.imageUrl ==>Defult Ast //_Treelist_Out.Name==>Defult Ast //_Treelist_Out.ParentId==>Defult Ast //_Treelist_Out.ExtraID ==>Defult ast _Treelist_Out.TreeListItm = TreelistChild(_Treelist, RootID); if (_Treelist.Where(n => n.ParentId == RootID).Count() > 0) { _Treelist_Out.HasChildren = true; } else { _Treelist_Out.HasChildren = false; } #endregion return _Treelist_Out; } private List<Treelist> TreelistChild(List<Treelist> _MainTreeList, int Parent) { List<Treelist> _ListTreeOut = new List<Treelist>(); List<Treelist> _ListChild = _MainTreeList.Where(n => n.ParentId == Parent).ToList(); if (_ListChild.Count > 0) { foreach (var item in _ListChild) { Treelist p1 = new Treelist(); p1.Checked = item.Checked; if (_MainTreeList.Where(n => n.ParentId == item.Id).Count() > 0) { p1.HasChildren = true; } else { p1.HasChildren = false; } p1.Id = item.Id; p1.ExtraID = item.ExtraID; p1.imageUrl = item.imageUrl; p1.Name = item.Name; p1.ParentId = item.ParentId; p1.TreeListItm = TreelistChild(_MainTreeList, item.Id); _ListTreeOut.Add(p1); } } return _ListTreeOut;
این کلاس حاوی دومتد که متد LoadTreeByBindingModel برای لود شدن والد ها و متد TreelistChild برای لود شدن زیر مجموعه ها (Child) به کار میرود .
حال در کنترلر User رفته و یک متد برای برای ذخیره کاربر و نوع سطح دسترسی آن ایجاد میکنیم
public ActionResult TreeView(int id) { var PermissionID = db.Permissions.Find(id); ViewBag.PermissionTitle = PermissionID.PermissionTitle; var _TreeLoad = db.Permissions.ToList(); List<Treelist> _TreeList = new List<Treelist>(); var users = db.Users.First().UserID; foreach (var item in _TreeLoad) { Treelist p = new Treelist(); p.Id = item.PermissionID; p.ParentId = item.ParentID; p.Name = item.PermissionTitle; p.Checked = db.Users_Permissions.Where(m=>m.PermissionID==id).Any(n => n.PermissionID == item.PermissionID ); //در اینجا ما فرض کردیم تمام گره ها تیک خورده هستند اگر می خواهید بایند شود کافی از روی دیتا بیس چک کنید p.ExtraID = id; //این برای این است که اطلاعات اضافی همراه داشته باشد مثلا این گره مربوط به کدام گروه است _TreeList.Add(p); } TreeClasses _TreeClasses = new TreeClasses(); Treelist _TreelistMain = _TreeClasses.LoadTreeByBindingModel(_TreeList, 1); return View(_TreelistMain); }
یک ورودی از جنس int به نام id میگیریم این کار برای گرفتن والد یا (همان ParntID)اصلی است
حال یک View ساخته و کد های زیر را داخل آن مینویسیم
@{ ViewBag.Title = "Index"; } @model Permission_MVC.Areas.AdminManager.Models.Treelist @Html.Action("CreatePartialViewByTreeListModel", "Users", new { _Tree = @Model, AddressSelectedNode = "/AdminManager/Users/SaveNodes" });
همان طور که مشاهده میکنید View را به متد CreatePartialViewByTreeListModel ارسال کردیم در این مرحله به ایجاد متد بالامیپردازیم
public ActionResult CreatePartialViewByTreeListModel(Treelist _Tree, string AddressSelectedNode) { ViewBag.AddressSelectedNode = AddressSelectedNode; return PartialView(_Tree); }
در واقع کار متد بالا نمایش سطوح دسترسی با treeview است حال یک view از متد بالا ایجاد میکنیم
model Permission_MVC.Areas.AdminManager.Models.Treelist <link href="~/Scripts/humane_js_themes/bigbox.css" rel="stylesheet" /> <style> .tree li { margin: 0px 0; list-style-type: none; position: relative; padding: 5px 50px 0px 5px; } .tree li::before { content: ''; position: absolute; top: 0; width: 35px; height: 100%; left: auto; right: -20px; border-left: 2px solid #ccc; bottom: 50px; } .tree li::after { content: ''; position: absolute; top: 15px; width: 35px; height: 20px; left: auto; right: 14px; border-top: 2px solid #ccc; } .tree li a { display: inline-block; /*border: 1px solid #ccc;*/ padding: 1px 5px 0 10px; text-decoration: none; color: #666; font-family: bkoodaks,Tahoma,'Open Sans',sans-serif; font-size: 14px; font-weight: 600; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; } /*Remove connectors before root*/ .tree > ul > li::before, .tree > ul > li::after { border: 0; } /*Remove connectors after last child*/ .tree li:last-child::before { height: 15px; } /*Time for some hover effects*/ /*We will apply the hover effect the the lineage of the element also*/ .tree li a:hover, .tree li a:hover + ul li a { background: #dd4814; color: #ffffff; /*border: 1px solid #dd4814;*/ } /*Connector styles on hover*/ .tree li a:hover + ul li::after, .tree li a:hover + ul li::before, .tree li a:hover + ul::before, .tree li a:hover + ul ul::before { border-color: #dd4814; } .tree-checkbox { margin: 4px !important; } .tree:before { border-left: 1px solid #ccc; bottom: 16px; content: ""; display: block; right: 0; /*position: relative;*/ top: -21px; width: 1px; z-index: 1; } .tree ul:after { /*border-top: 1px solid #ccc;*/ content: ""; height: 20px; right: -29px; position: absolute; left: auto; top: 37px; width: 34px; } *:before, *:after { box-sizing: border-box; } *:before, *:after { box-sizing: border-box; } .tree { overflow: auto; padding-right: 0px; position: relative; } label { float: left; } </style> <div class="row-fluid"> <div id="frm-author"> @using (Html.BeginForm("SaveNodes", "Users", FormMethod.Post, new { encType = "multipart/form-data" })) { @Html.HiddenFor(model => model.ExtraID) <div class="tree"> @if (1 == 1) { <ul> <li> <a> @Html.CheckBoxFor(model => @Model.Checked, new { @class = "tbkh tree-checkbox parent", @id = @Model.Id, @kk = @Model.ExtraID }) <label for=@Model.Id> @Html.DisplayFor(model => @Model.Name) </label> </a> @*------------------Level2--------------------------------------------------------*@ @if (@Model.TreeListItm != null && @Model.TreeListItm.Count() > 0) { <ul> @foreach (var itemChild1 in @Model.TreeListItm) { <li> <a> @Html.CheckBoxFor(model => itemChild1.Checked, new { @class = "tbkh tree-checkbox node-item", @id = @itemChild1.Id, @kk = @itemChild1.ExtraID }) <label for=@itemChild1.Id> @Html.DisplayFor(model => @itemChild1.Name) </label> </a> @*------------------Level3-------------------------------------------------------*@ @if (@itemChild1.TreeListItm.Count() > 0) { <ul> @foreach (var itemChild3 in @itemChild1.TreeListItm) { <li> <a> @Html.CheckBoxFor(model => itemChild3.Checked, new { @class = "tbkh tree-checkbox node-item", @id = @itemChild3.Id, @kk = @itemChild3.ExtraID }) <label for=@itemChild3.Id> @Html.DisplayFor(model => @itemChild3.Name) </label> </a> @*------------------Level4-------------------------------------------------------*@ @if (@itemChild3.TreeListItm.Count() > 0) { <ul> @foreach (var itemChild4 in @itemChild3.TreeListItm) { <li> <a> @Html.CheckBoxFor(model => itemChild4.Checked, new { @class = "tbkh tree-checkbox node-item", @id = @itemChild4.Id, @kk = @itemChild4.ExtraID }) <label for=@itemChild4.Id> @Html.DisplayFor(model => @itemChild4.Name) </label> </a> @*------------------Level5-------------------------------------------------------*@ @if (@itemChild4.TreeListItm.Count() > 0) { <ul> @foreach (var itemChild5 in @itemChild4.TreeListItm) { <li> <a> @Html.CheckBoxFor(model => itemChild5.Checked, new { @class = "tbkh tree-checkbox node-item", @id = @itemChild5.Id, @kk = @itemChild5.ExtraID }) <label for=@itemChild5.Id> @Html.DisplayFor(model => @itemChild5.Name) </label> </a> </li> } </ul> } @*------------------Level5--------------------------------------------------------*@ </li> } </ul> } @*------------------Level4--------------------------------------------------------*@ </li> } </ul> } @*------------------Level3--------------------------------------------------------*@ </li> } </ul> } @*------------------Level2--------------------------------------------------------*@ </li> </ul> } </div> } <div class="row-fluid"> <div class="row-form"> <button class="btn btn-success pull-left" id="btnSubmit2" onclick="SelectedNodeChecked(1);"> ذخیره تغییرات </button> <a href="/AdminManager/Users/Index" class="btn pull-right">بازگشت به لیست اصلی</a> </div> </div> </div> </div> <div id="ModalCreate"> </div> <script src="~/Scripts/humane.min.js"></script> <script type="text/javascript"> function SelectedNodeChecked(id) { var checked = []; $(".tbkh").each(function (index, element) { if ($(this).is(":Checked")) { var i; i = $(this).attr('id'); checked.push(i); } }); var roleId = $("#ExtraID").val(); $.ajax({ url: "@ViewBag.AddressSelectedNode", type: "POST", data: "id=" + checked + "&PermissionID=" + roleId, success: function (result) { updateSuccess(); $('#myModal').modal('hide'); window.location.href = "/AdminManager/Users/Index"; } }); }; function updateSuccess(data) { $('#ModalCreate').modal('hide'); humane.log("اطلاعات با موفقیت ثبت گردید"); } </script>
در این مرحله تا 5 سطر ، دسترسی میتوان تعریف کرد و ما با استفاده از Ajax قصد داریم وقتی کاربر سطوح دسترسی را انتخاب کرد در بانک ذخیره شود
در این قسمت کد ثبت را مینوسیم
public ActionResult SaveNodes(string id, string PermissionID) { if (id.Trim() != "" && PermissionID.Trim() != "") { var pID = int.Parse(PermissionID); var Permissionresult = db.Users_Permissions.Where(m => m.PermissionID == pID).ToList(); foreach (var item in Permissionresult) { db.Users_Permissions.Remove(item); } db.SaveChanges(); foreach (string s in id.Split(char.Parse(","))) { db.Users_Permissions.Add(new Users_Permissions() { PermissionID = int.Parse(s), UserID = pID }); } db.SaveChanges(); } return null; }
اگر به کد Ajax ای که در view نوشتیم دقت کنید دو تا پارامتر به نام های id , PermissionID گرفتیم که در متد SaveNodes آن ها رابه عنوان پارامتر ورودی گرفتیم
متغیر PermissionID ، برای پاس دادن ئ به جدول Users_Permissions و متغیر id برای گرفتن id کاربر به کار میرود
و همان طور که مشاهده میکنید ایتدا تمام سطوح دسترسی را پاک کرده و سپس اضافه میکنیم
- ASP.net MVC
- 5k بازدید
- 22 تشکر