PDA

View Full Version : سوال: روش بدست آورن Role کاربر ؟ و جستجوی کاربران بر اساس Role ها در Identity 2.1 ؟



alibahman47
پنج شنبه 05 مرداد 1396, 10:13 صبح
درود ,

http://s8.picofile.com/file/8301760076/Identity_2.jpg


در ابتدا سوال خیلی مهمی که برام پیش اومده اینه که چرا در ساختار Identity از جدول UserRoles استفاده شده ؟!!!
بدوم جدول UserRoles هم براحتی میتوان بین جداول Users و Roles ارتباط برقرار کرد و Role مربوط به هر کاربر را مشخص کرد - این دقیقا کاری است که من در کل پایگاه داده هایی که تا به حال طراحی کردم استفاده میکنم و هیچگاه برای ارتباط بین دو جدول از ی جدول واسط بینشون استفاده نمیکنم و هیچ دلیلی هم برای استفاده نیست.


سوالات :
1- دوستانی که تخصص و اطلاعات کامل تری دارند درصورت امکان یه توضیح کوتاه بدن که چرا از جدول UserRoles استفاده شده و آیا میشه کلا برش داشت و حذفش کرد یا بخاطر امنیت یا مسله دیگه ای وجودش ضروری هست ؟

2 - اگر جدول UserRoles وجود نداشت به راحتی میشد در زمان نمایش کل کاربران , نام role هر کاربر را بدست آورد یا بر اساس یک نام role (که از کاربر دریافت شود) فقط کاربرانی که اون نقش رو دارند جستجو کرد و برگشت داد ولی با توجه به این جدول واسطه همه چیز برای من برای انجام این کار ها غیر ممکن شده و نمیدونم چطوری باید کدش رو نوشت !

با توجه به رابطه فعلی جداول کد مربوط به دوتا کار زیر به چه شکله ؟

3 - نمایش Name مربوط به Role یک کاربر (البته در زمانی که همه کاربران رو در یک جدول پیجر نمایش میدیم - یعنی در هر سط که اطلاعات کاربر نمایش می یابد نقش اون هم نمایش یابد) ؟

4 - Name یک Role را بگیریم و کاربرانی که فقط آن نقش را دارند جستجو کنیم ؟

alibahman47
پنج شنبه 05 مرداد 1396, 21:20 عصر
خلاصه سوال بنده : در زمانی که داریم لیست همه کاربران رو نشون میدم اگر بخوام در هر سطری که اطلاعات یک کاربر نمایش می یابد نام Role (یا role ها) را هم نشان دهیم , چه کدی باید نوشت ؟
توجه کنید که در View این کد رو باید بنویسیم !




Click here to view the original image of 881x676px.
http://s8.picofile.com/file/8301815842/Role_Name.png

دوستانی که با Identity 2.1 در Mvc 5.2.3 اشنای دارم اگه ممنه یه راهنمایی بکنن ؟

ali_md110
جمعه 06 مرداد 1396, 02:16 صبح
رابطه کاربر و نقش یک رابطه چند به چند هست و بهترین روش پیاده سازی همین جوری هست که در Identity اومده و حتمن به یگ جدول واسط نیاز هست
و در ضمن شما ممکنه بگید روشتون چجوریه برای یک رابطه چند به چند؟
دارید دوتا رابطه یک به چند میسازید؟
هرجور باشه احتمالا جامعیت بانک رو دارید از بین میبرید

و در مورد سوال تاپیک دومتون
شما نیاز به یک وبومدل دارید که توی اون یک کالکشن یا یک ارایه از نوع string تعریف کنید برای نگهداری نام رول ها

و یگ فیلد برای نگهداری نام گاربری مثل UserName
بعد کوئری که میزنید بضورت SelectMany اجرا کنید



var i= await Users.SelectMany(role => role.Roles, (user, userRole) => new { user, userRole })

.Select(t => new RoleViewModel
{
UserName = t.user.UserName,
Rols = t.user.Roles.ToArray()
}).ToListAsync();

البته از Automapper هم استفاده کنید بهتره

hakim22
شنبه 07 مرداد 1396, 07:42 صبح
اگر در پروژه ی شما هر نفر فقط میتونه یک Role داشته باشه راحت تره که یک فیلد جدید به User اضافه کنید و سمت هر کاربر رو در اون ذخیره کنید.
سیستم Identity بر اساس Role-based Authentication کار میکنه و یک کاربر میتونه چند سمت داشته باشه و بر اساس هر سمت دسترسی مشخصی داشته باشه.

همچنین Identity دارای یک کلاس UserManager هست که به شما امکان مدیریت اطلاعات و سمتهای همه ی کاربرهارو میده.


UserManager<ApplicationUser> userManager


برای پیدا کردن سمتهای یک کاربر یا کم و زیاد کردن اون می توانید از کلاس UserManager استفاده کنید.

alibahman47
شنبه 07 مرداد 1396, 10:25 صبح
اگر در پروژه ی شما هر نفر فقط میتونه یک Role داشته باشه راحت تره که یک فیلد جدید به User اضافه کنید و سمت هر کاربر رو در اون ذخیره کنید.
سیستم Identity بر اساس Role-based Authentication کار میکنه و یک کاربر میتونه چند سمت داشته باشه و بر اساس هر سمت دسترسی مشخصی داشته باشه.

همچنین Identity دارای یک کلاس UserManager هست که به شما امکان مدیریت اطلاعات و سمتهای همه ی کاربرهارو میده.


UserManager<ApplicationUser> userManager


برای پیدا کردن سمتهای یک کاربر یا کم و زیاد کردن اون می توانید از کلاس UserManager استفاده کنید.


حرف شما درسته و من با این کلاس آشنایی دارم اما کاربرد این مورد وقتی هست که مثلا کاربرد این مورد وقتی هست که مثلا بخوایم جزییات اطلاعات یک کاربر رانمایش بدیم (یعنی در سمت کنترولر با این کلاس کار کنیم) و با استفاده ازین کلاس Role های کاربر موردنظر را بدست میآوریم و نشان میدیم - بنده این ار رو کردم و مشکلی ندارم :

145898
http://s9.picofile.com/file/8301936426/Details.jpg
سوال من برای موقعی هست که لیست تمامی کاربران را نمایش میدهیم :
http://s9.picofile.com/file/8301936418/Users.png

اگر بخواهیم در هر سط نام Role های کاربر نمایش یابد باید در سمت View چه کدی را نوشت ؟

دیگه واضح تر ازین نمیدونم چطوری توضیح بدم که منظورم رو برسونم - امیوارم منظورم رو گرفته باشید !

alibahman47
شنبه 07 مرداد 1396, 10:41 صبح
رابطه کاربر و نقش یک رابطه چند به چند هست و بهترین روش پیاده سازی همین جوری هست که در Identity اومده و حتمن به یگ جدول واسط نیاز هست
و در ضمن شما ممکنه بگید روشتون چجوریه برای یک رابطه چند به چند؟
دارید دوتا رابطه یک به چند میسازید؟
هرجور باشه احتمالا جامعیت بانک رو دارید از بین میبرید

و در مورد سوال تاپیک دومتون
شما نیاز به یک وبومدل دارید که توی اون یک کالکشن یا یک ارایه از نوع string تعریف کنید برای نگهداری نام رول ها

و یگ فیلد برای نگهداری نام گاربری مثل UserName
بعد کوئری که میزنید بضورت SelectMany اجرا کنید



var i= await Users.SelectMany(role => role.Roles, (user, userRole) => new { user, userRole })

.Select(t => new RoleViewModel
{
UserName = t.user.UserName,
Rols = t.user.Roles.ToArray()
}).ToListAsync();

البته از Automapper هم استفاده کنید بهتره

ممکنه یه خورده بیشتر توضیح بدید ؟
این کد رو باید کجا نوشت ؟
و چطور در سمت ویو و در زمان نمایش لیست کاربران ازش استفاده کنم ؟

ali_md110
شنبه 07 مرداد 1396, 14:46 عصر
این یک درخواست هست که بصورت یک لیست جنریکه میتونید همه جا بنویسید توی یک کنترولر یا یک کلاس سرویس دهنده
و سپس از سمت کنترولر اونو به ویو پاس بدید و با یک حلقه در سمت ویو انو پیمایش کنید و نشون بدیدش

و از


UserManager<ApplicationUser> User

که جناب حکیم گفتند استفاده شده
روش استفاده اینه یک کلاسApplicationUserManager ّبسازید و با ارث بری از UserManager<ApplicationUser> از متدهای پیش فرض و Dbset های اون بهره ببرید


public class ApplicationUserManager
: UserManager<ApplicationUser, int>
{

private readonly IUserStore<ApplicationUser, int> _store;
public ApplicationUserManager(IUserStore<ApplicationUser, int> store,
)
: base(store)
{
_store = store;

}
}

Moien Tajik
شنبه 07 مرداد 1396, 17:24 عصر
روش هایی که دوستان گفتن درست هستش ، اما کمی پیچیده هستن و روش راحتری هم هست .

داخل ApplicationUser ، یک Property جدید از نوع IEnumerable اضافه کنید :


public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
ClaimsIdentity userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}


public IEnumerable<string> RolesList { get; set; }
}


در نهایت داخل کنترلر و گرفتن تمام کاربران :


public ActionResult Index()
{
List<ApplicationUser> users = UserManager
.Users
.ToList();


foreach (ApplicationUser user in users)
user.RolesList = UserManager.GetRoles(user.Id);
return View(users);
}


و در ویو :


@foreach (ApplicationUser user in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => user.Email)
</td>
<td>
@Html.DisplayFor(modelItem => user.UserName)
</td>
<td>
@foreach (string role in user.RolesList)
{
@Html.DisplayFor(modelItem => role) <br />
}
</td>
</tr>
}


دانلود Sample این پروژه : http://uplod.ir/qvbnoiumck5v/IterateRoles.zip.htm

alibahman47
یک شنبه 08 مرداد 1396, 11:29 صبح
اول اینکه همونطور که در تصویر مشخصه من دارم از پیجر استفاده میکنم و همینطور ViewModel و نمیتونم بیام از دوتا ViewModel هم استفاده کنم و یا یم ViewModel بصورت کالشن رو با ViewModel جاری خودم ترکیب کنم و یا هر چیز دیگه ای ...

جدا ازینکه کسایی که تاپیک ها رو جواب میدن ,این لطفشون رو میرسونه ولی خدایی نمیدونم چرا بعضی از دوستان انقدر مباحث رو پیچیده میکنن , که آدم فقط گیج میشه !
شاید دلیلش این باشه که شما خیلی حرفه ای کار میکنید و کلا نگاهتون به همه مسایل پیچیده و متفاوته !

نهایتا مشکل با نوشتن خط 17 در تصوریر زیر - ViewModel که دارم :

http://s9.picofile.com/file/8302040634/1.jpg


و کد زیر در کنترولر :

http://s9.picofile.com/file/8302038068/2.jpg
و در View

http://s8.picofile.com/file/8302038168/3.jpg
مشکل حل شد.
خداییش نه کار سختی بود و نه نیاز به نوشتن N خط کد بود و نه نیاز به دونستن مباحث خیلی پیچیده - کلش 3 خط کد بود.



البته من چون قبلش به جواب رسدم روش آقای Moien Tajik رو امتحان نکردم(البته جواب های ایشون همیشه دقیق و درستن ) .