آموزش کار با Role در MVC

یکشنبه 21 شهریور 1395

هدف از این مقاله ، آموزش چگونگی ایجاد Role ، تغییر دادن Role ، حذف Role و مدیریت Role با استفاده از ASP.Net Identity در MVC برای یک کاربر خاص است .

آموزش کار با Role در MVC

معرفی :
ASP.Net Identity تقریبا همه ویژگی های مورد نیاز برای احراز هویت را فراهم میکند و اجازه قانونی (authorization) برای برنامه Asp.Net همچنین اضافه کردن یک Role جدید ، و انتساب آن به یک کاربر خاص ، به نظر می‌رسد که در تمام این ویژگی ها فراموش شده است . در این مقاله ما همه چیز را در مورد ایجاد Role ، تغییر دادن Role ، حذف Role  و مدیریت Role برای یک کاربر خاص در ASP.Net MVC 5 را خواهیم آموخت . 

مفروضات :
در این جا فرض ما بر این است که خواننده این مقاله اطلاعات ابتدایی در مورد ASP.Net MVC دارد و چگونگی کار با View , Controller و Entity Framework را میداند . 

با مدیریت Role در ASP.Net Identity شروع میکنیم :

بصورت پیش فرض زمانی که یک برنامه ASP.NET MVC default اجرا می‌شود و migration خودکار روشن است ، ثبت نام یک کاربر بصورت خودکار جداولی را در پایگاه داده ایجاد میکند که عبارت اند از :

1. AspNetRoles - اطلاعات Role را ذخیره می‌کند و شامل ستون های Id و Name می‌باشد   .

2. AspNetUsers - اطلاعات کاربر را ذخیره می‌کند و شامل ستون‌های Id, UserName, PasswordHash, SecurityStamp و Discriminator می‌باشد . 

3. AspNetUserRoles - شناسه(id) مربوط به کاربر و Role را ذخیره می‌کند و شامل ستون های UserId و RoleId می‌باشد .


توضیح و بررسی جدول‌های دیگر در مورد بحث ما نیست و در این مُقال نمی‌گنجد .



به صورت پیش فرض ، ما کلاس پیش فرض Model را برای ASP.Net Identity که با جداول پایگاه داده در رابطه است ، در نظر نمی‌گیریم ، بنابراین ، نیاز است که View و Controller را بصورت دستی ایجاد کنیم . در این مورد ، ما فولدر Controller  و View جدا برای Roleها داریم .

مفروضات برنامه :
در اینجا ، فرض ما بر این است که ما هم اکنون یک کلاس  IdentityModels.cs در فولدر Models داریم که کدهای آن شبیه کدهای زیر است (در ASP.Net MVC 5 ، این بصورت خودکار ساخته می‌شود)

// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
        }
    }


در تمام Action متدهای RolesController ، صفتی برای Authorize ، برای اینکه کدها را ساده و قابل فهم کند ، مورد استفاده قرار می‌گیرد

ایجاد یک Role جدید با  ASP.NET Identity :

برای ایجاد یک Role جدید ، view و تکه کد زیر را داریم .



@{
    ViewBag.Title = "Create";
}

<h2>Create Role</h2>
@Html.ActionLink("List Roles", "Index") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr/>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <div>
        Role name
    </div>
    <p>
        @Html.TextBox("RoleName")
    </p>
    <input type="submit" value="Save" />
}


در تیکه کد بالا ، یک TextBox ساده با نام RoleName و یک فرم عمومی مرتبط با کد داریم لطفا توجه داشته باشید که در اینجا دایرکتیو model@ نداریم . متد Controller همانند زیر است :

Namespaceهایی که برای کار با Roleها نیاز است ، در زیر مشاهده می‌کنید :

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;


متد Controller برای ایجاد View همانند زیر است :

  // GET: /Roles/Create
        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Roles/Create
        [HttpPost]
        public ActionResult Create(FormCollection collection)
        {
            try
            {
                context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
                {
                    Name = collection["RoleName"]
                });
                context.SaveChanges();
                ViewBag.ResultMessage = "Role created successfully !";
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

اولین متد Create یک View ساده را بازمی‌گرداند ، دومین متد Create ، شئ FormCollection را به عنوان پارامتر می‌پذیرد و از شئ Context (نمونه ای از ApplicationDbContext) برای اضافه کردن Role به مجموعه Role ها ، استفاده می‌کنیم  . توجه داشته باشید که ، نام جدول Roleها در پایگاه داده AspNetRoles و نام کلاس Model ما IdentityRole می‌باشد . فراخوانی متد SaveChange ، نقش(Role) جدید را در پایگاه داده ذخیره میکند .

 فهرست Roleها با ASP.NET Identity :


  

فهرست بندی Roleها با استفاده از ASP.NET Identity ، کدهای View زیر را داریم :

@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>
@{
    ViewBag.Title = "Index";
}

<h2>Roles Listing </h2>

@Html.ActionLink("Create New Role", "Create") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr/>
<div>
    @foreach (var role in Model)
{
    <p><strong>@role.Name | </strong> 
    <span onclick="return confirm('Are you sure to delete?')"><a href="/Roles/Delete?RoleName=@role.Name" class="delLink" style="color:red;">Delete</a></span> | 
    @Html.ActionLink("Edit", "Edit", new { roleName = @role.Name })
    </p>
}
</div>

در تکه کد بالا ، model این IdentityRole ، View است و در حلقه foreach ، همه role ها از مجموعه roleها لیست میشوند . زمانی که roleها فهرست شد ، همچنین یک link برای حذف و ویرایش یک role خاص ، ایجاد می‌کنیم .

متد Controller برای لیست کردن roleهای ASP.NetIdentity بصورت زیر است :

       public ActionResult Index()
        {
            var roles = context.Roles.ToList();
            return View(roles);
        }


در تکه کد بالا ، مجموعه Roleها را از ApplicationDbContext دریافت می‌کنیم و آن را به View بازمی‌گردانیم . 


حذف یک Role  با استفاده از ASP.Net Identity :

کلیک کردن روی لینک delete در فهرست roleها ، باعث حذف یک Role خاص از پایگاه داده می‌شود و در اینجا یک Action متد برای این ، در RolesController وجود دارد . 

public ActionResult Delete(string RoleName)
        {
            var thisRole = context.Roles.Where(r => r.Name.Equals(RoleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
            context.Roles.Remove(thisRole);
            context.SaveChanges();
            return RedirectToAction("Index");
        }


ما Role انتخاب شده را از پایگاه داده انتخاب کردیم و متد Remove را از مجموعه Roleها فراخوانی کردیم . فراخوانی متد شئ 
ApplicationDbContext ، نقش انتخابی را از پایگاه داده حذف می‌کند . 

 ویرایش Role با استفاده از ASP.NET Identity :




برای ویرایش Role ، کد زیر و view بالا را داریم :

@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
@{
    ViewBag.Title = "Edit";
}

<h2>Edit Role</h2>

@Html.ActionLink("List Roles", "Index") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr />
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    @Html.HiddenFor(model => model.Id)
    <div>
        Role name
    </div>
    <p>
        @Html.TextBoxFor(model => model.Name)
    </p>
    <input type="submit" value="Save" />
}


در کد بالا ، IdentityRole کلاس model ماست . 

متد Edit در Contoller همانند زیر است :

    //
        // GET: /Roles/Edit/5
        public ActionResult Edit(string roleName)
        {
            var thisRole = context.Roles.Where(r => r.Name.Equals(roleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();

            return View(thisRole);
        }

        //
        // POST: /Roles/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Microsoft.AspNet.Identity.EntityFramework.IdentityRole role)
        {
            try
            {
                context.Entry(role).State = System.Data.Entity.EntityState.Modified;
                context.SaveChanges();

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }


در تکه کد بالا ، اولین متد roleName را به عنوان پارامتر میپذیرد و بر اساس آن ، ما role را از پایگاه داده بازیابی کرده و به view بازمیگردانیم . 

دومین متد ، IdentityRoleرا به عنوان پارامتر دریافت می‌کند و رکورد را در پایگاه داده بروزرسانی می‌کند . 

مدیریت Roleها برای یک کاربر خاص در ASP.NET Identity :

برای مدیریت Roleها برای یک کاربر خاص در ASP.NET Identity ، ما view زیر را داریم که دارای بیش از یک form میباشد :

1. یک role برای کاربر اضافه کنید .
2. roleها را برای کاربر گرفته و 
3. Delete/Detach یک کاربر از یک نقش خاص 




کد برای view بالا همانند زیر است :

@{
    ViewBag.Title = "ManageUserRoles";
}

<h2>Manage User Roles</h2>
@Html.ActionLink("Create New Role", "Create") | @Html.ActionLink("Manage User Role", "ManageUserRoles")
<hr/>

<h2>Role Add to User</h2>

@using (Html.BeginForm("RoleAddToUser", "Roles"))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <p>
        Username : @Html.TextBox("UserName")
        Role Name: @Html.DropDownList("RoleName", (IEnumerable <SelectListItem>) ViewBag.Roles, "Select ...")

    </p>

    <input type="submit" value="Save" />
}
<hr/>
<h3>Get Roles for a User</h3>
@using (Html.BeginForm("GetRoles", "Roles"))
{
    @Html.AntiForgeryToken()
    <p>
        Username : @Html.TextBox("UserName")
        <input type="submit" value="Get Roles for this User" />
    </p>
}

@if (ViewBag.RolesForThisUser != null)
{
    <div style="background-color:yellow;">
        <h3>Roles for this user </h3>
        <ol>
            @foreach (string s in ViewBag.RolesForThisUser)
            {
                <li>@s</li>
            }
        </ol>
    </div>
}

<hr />
<h3>Delete A User from a Role</h3>

@using (Html.BeginForm("DeleteRoleForUser", "Roles"))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <p>
        Username : @Html.TextBox("UserName")
        Role Name: @Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")

    </p>

    <input type="submit" value="Delete this user from Role" />
}


متد ManageUserRoles  در Controller همانند زیر است :

public ActionResult ManageUserRoles()
        {
            // prepopulat roles for the view dropdown
            var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => 

new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = list;   
            return View();
        }


فهرست roleها را دریافت می‌کنیم و آن را روی ViewBag تنظیم میکنیم که برای DropDown ای که در view قرار دارد مورد استفاده قرار می‌گیرد .

اضافه کردن یک role به کاربر با استفاده از ASP.Net Identity :

اولین فرم دارای یک UserName TextBox و RoleName dropdown list است که شامل roleهایی که در پایگاه داده ما قرار دارد ، هست .  Submit کردن فرم ، اطلاعات فرم را به Action متد ِ RolesController ، RoleAddToUser  ارسال می‌کند . 

      [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult RoleAddToUser(string UserName, string RoleName)
        {
            ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
            var account = new AccountController();
            account.UserManager.AddToRole(user.Id, RoleName);
            
            ViewBag.ResultMessage = "Role created successfully !";
            
            // prepopulat roles for the view dropdown
            var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = list;   

            return View("ManageUserRoles");
        }


در متد بالا ، UserName و RoleName را به عنوان پارامتر دریافت می‌کنیم . 

UserName برای گرقتن ApplicationUser از Context مورد استفاده قرار می‌گیرد . مجموعه کاربران ، سپس 
شئ AccountController برای پردازش property شئ UserManager مورد استفاده قرار می‌گیرد و متد AddToRole را بوسیله ارسال UserId از شئ ApplicationUser ، فراخوانی می‌کند و RoleName به درون فرم می‌آید .

چند خط باقی مانده برای لیست کردن role ها در DropDown است . 

گرفتن Roleها برای یک کاربر در ASP.Net Identity :



در فرم دوم ،  ما یک UserName TextBox و یک button داریم . کلیک کردن روی button فرم را برای Action متد GetRoles ارسال میکند . 

متد Controller ، GetRoles ما همانند زیر است :

 [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult GetRoles(string UserName)
        {            
            if (!string.IsNullOrWhiteSpace(UserName))
            {
                ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
                var account = new AccountController();

                ViewBag.RolesForThisUser = account.UserManager.GetRoles(user.Id);

                // prepopulat roles for the view dropdown
                var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
                ViewBag.Roles = list;            
            }

            return View("ManageUserRoles");
        }


حذف یک کاربر از یک Role :

در فرم سوم ، ما یک UserName TextBox و یک RoleName dropdown list داریم . کلیک کردن بر روی Button فرم را به action متد DeleteRoleForUser  ارائه میدهد ، و تکه کد های زیر مربوط به این است :

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteRoleForUser(string UserName, string RoleName)
        {
            var account = new AccountController();
            ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();

            if (account.UserManager.IsInRole(user.Id, RoleName))  
            {
                account.UserManager.RemoveFromRole(user.Id, RoleName);
                ViewBag.ResultMessage = "Role removed from this user successfully !";
            }
            else
            {
                ViewBag.ResultMessage = "This user doesn't belong to selected role.";
            }
            // prepopulat roles for the view dropdown
            var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
            ViewBag.Roles = list;

            return View("ManageUserRoles");
        }

در تکه بالا ، ما ApplicationUser  را دریافت میکنیم و سپس چک می‌کنیم که آیا این کاربر ارتباطی با Role انتخاب شه دارد یا نه ، اگر دارد ، متد RemoveFromRole با ارسال پارامترهای  UserId و RoleName ، فراخوانی می‌شود ، که کاربر را از Role حذف می‌کند . 


نتیجه‌گیری :
ما در این مقاله ، چگونگی توسعه یک رابطه کاربری برای ایجاد یک Role جدید ، ویرایش آن ، حذف آن ، ضمیمه کردن یک View Role به یک کاربر خاص و مدیریت یک role برای یک کاربر خاص توسط ASP.Net Identity در
ASP.Net MVC را آموختیم .

امیدواریم که این مقاله برای شما مفید واقع شده باشد . 



آموزش asp.net mvc


فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید