PDA

نسخه کامل مشاهده نسخه کامل : روش بدست آورن Role کاربر ؟ و جستجوی کاربران بر اساس Role ها در Asp.net Mvc 5 Identity 2.1 ؟



ali_i3
27-07-2017, 10:05
درود ,

[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]


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


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

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

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

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

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

shaahani
27-07-2017, 10:54
ببینید این بر میگرده به اصول اصلی طراحی بانک های داده رابطه ای
وجود جدول یوزر رول کاملا ضروری هست به دلایل بسیار زیادی
اولین مسئله که در بانک اطلاعاتی بسیار اهمیت دارد سرعت است؛ با ایندکس گذاری و دادن شماره به هرکدام از رکورد ها سرعت جستجو و یافتن راحت تر اطلاعات از نظر سخت افزاری بر روی دیسک ذخیره اطلاعات بیشتر میشه و طراحان حرفه ای به هیچ عنوان از آن چشم پوشی نمیکنند.

مسئله دیگری که وجود دارد جلوگیری از افزونگی اطلاعات است ؛ نباید اجازه داد اطلاعات بطور تکراری در بانک داده ذخیره بشه ؛ علاوه بر افزایش حجم و کندی سرعت ؛ عملیات ویرایش و غیره بسیار دشوار می شود و احتمام رخدادن خطا بسیار بسیار بالا می رود ؛ یک طراح حرفه ای هرگز چنین ریسکی را نمی پذیرد
مثلا در این نمونه می بایست برای هرکاربر یک فیلد دیگه اضافه میشد که دسترسی به اون سخت بود و اگر به عنوان مثال قرار بود نام یک رول تغییر داده بشه ؛ میبایست تک تک تمام جدول یوزر برای تغییر نام یک رول ویرایش میشد ؛ علاوه بر حجم سنگین پردازیشی که به سیستم اعمال می شد ؛ احتمال رخ دادن خطا بسیار بالا میرفت ؛ اما در طراحی که مشاهده میکنید کافیه نام رل به سادگی در یک رکورد تغییر کند تا تمام کاربران نام جدید رول خود را مشاهده کنند.

مسئله دیگر ارتباط یک به چند است که در این نوع ترکیب میتوان از آن استفاده کرد . اگر یک کاربر بخواهد چند رول مختلف داشته باشد آن وقت چه ؟
اگر یک فیلد نام رول در جدول کاربران وجود داشت باید چندین بار کل رکورد یک کاربر کپی برداری بشه و آن وقت هرکاربر در این جدول بجای یک رکورد چندین رکورد مختلف خواهد داشت که این باعث ازهم گسیختگی و از بین رفتن نظم در این جدول و کل سیستم میشد و بازهم با مسئله افزونگی اطلاعات روبرو خواهیم بود و بارها و بارها اطلاعات تکراری مشخصات یک کاربر در این جدول کپی میشد و حذف و ویرایش آنهم دردسر ها و تحمیل بار اضافه به سیستم بود ؛ علاوه بر اینکه افزایش هر چه بیشتر اطلاعات به معنی کندتر شدن کل سیستم خواهد بود و به هیچ عنوان نباید اجازه داده شود اطلاعات تکراری و اضافه ذخیره شود.

مسائل پیچیده و بنیادی دیگه ای هم در طراحی وجود داره که دیگه از توضیح دادن اونا صرف نظر میکنم ، بنابراین پاسخ شما این هست که وجود این جدول از نقطه نظر طراحی بسیار مهم و حیاتی است و عملا حذف ناشدنی ؛ اما اینکه می شود آنرا حذف کرد و یا خیر ؛ پاسخ بلی است ! شما میتوانید جدول های رول و یوزر رول را حذف کرده و یک فیلد به جدول یوزر اضافه کنید با نام RoleName ! البته این نوع ساخت و ساز من را به یاد طراحی های فارغ التحصیلان و مهندسان ایرانی کامپیوتر می اندازد !

الان که چنین طراحی بنیادی و دقیقی انجام شده ، شما همچنان براحتی تمام کارهایی که مورد نیازتون هست رو میتونید انجام بدین ؛ البته شاید به مقدار بیشتری تخصص در این زمینه احتیاج داشته باشین

برای اینکه بتوانیم در جدول اصلی اطلاعاتی از دیگر جدول های مرتبط شده را نمایش بدهید می بایست یک فیلد مجازی در جدول کاربران ایجاد کنیم که بر اساس شماره ID کاربر به شماره ID جدول رول متصل باشد و لوک آپ آن یا همان فیلد به نمایش در آمده فیلد Name در جدول رولز باشه
بنابراین برای نمایش اطلاعات در یک جدول ؛ حتما نیاز نیست تمامی فیلد ها بطور سخت افزاری در آن جدول ذخیره شده باشند و میشود با فیلد های لوکاپ و غیره اطلاعات مرتبط را به نمایش در آورد.

جستجو در مورد کاربران یک رول خاص ؛ اکنون نیز قابل انجام شدن با سرعت بسیار بالایی است ؛ فقط ممکن است کمی روند کار دشوار شده باشد.
شما نام یک رول را دریافت میکنید و شماره آن را در جدول یوزر رولز فیلتر میکنید تا مابقی رول ها مخفی شوند ، سپس رکورد های باقی مانده حاوی ID کاربرانی است که دارای آن رول بخصوص هستند و فقط کافی است با فیلد های لوکاپ ؛ جدول های مجازی و مسائلی از این دست با توجه به ID لیست آن کاربران بنمایش در بیاید.
و جالب تر این است که این روش جستجو بسیار سریع از آن است که بخواهید نام یک رول را که در فیلد جدید اضافه شده به جدول کاربران وجود دارد جستجو بفرمایید .
زیرا جستجو اولیه نام در یک جدول بسیار کوچک انجام میگیرد و مابقی جستجو ها فقط جستجو اعداد هستند که این نوع جستجو سرعت بسیار بالایی دارد.
همیشه دقت داشته باشین که عملیات جستجو با فیلتر بسیار سریعتر از اجرا هرگونه دستور SQL میباشد و بیشترین پردازش نیز مربوط به ضرب دکارتی یا همان فرمان join در جداول هست که تا جای ممکن از آنها باید اجتناب شود.


ببخشید که کوتاه و با بی حوصلگی پاسختون رو دادم ؛ پیشنهاد من این هست که برای بدست آوردن اطلاعات بیشتر و همچنین برای یافتن پاسخ چنین سوالاتی آن را در فروم ویژه برنامه نویسی ایران barnamenevis.org و یا فروم های خارجی برنانمه نویسی مطرح کنید و منابع خارجی نحوه انجام چنین کارهایی در زبان برنامه نویسی یا برنامه مورد استفاده خودتون ؛ مطرح ؛ پیگیری و مطالعه بفرمایید.

_H2_
27-07-2017, 13:24
سلام

...چرا از جدول UserRoles استفاده شده...
بدون وجود جدول کمکی شما فقط میتوانید روابط "یک به چند" ایجاد کنید.
ولی هرگاه نیاز به روابط "چند به چند" باشد از جدول کمکی استفاده میشود و این بسیار مرسوم است.
درواقع در بسته مایکروسافت "هر کاربر میتواند عضو چند Role باشد" و طبیعتا "هر Role هم میتواند شامل چند کاربر باشد"

باچیزی که شما پیشنهاد میکنید، هر کاربر میتواند فقط یک Role داشته باشد و این خیلی محدود است!
(((
تازه مایکروسافت این جریان را بسیار عادی و ساده دیده، در شرایط پیشرفته تر ما نیاز به Role های درختی هم پیدا میکنیم و یکسری مفاهیم دیگر...
ولی پیاده سازی فعلی مایکروسافت برای اکثر کارهای سطح متوسط بسیار خوب است
)))

اگر بخواهید از Identity استفاده کنید، گمان نکنم بتوانید جدول فوق را حذف کنید.


...نام role هر کاربر را بدست آورد یا بر اساس یک نام role (که از کاربر دریافت شود) فقط کاربرانی که اون نقش رو دارند...
مطمئن نیستم مشکل تان چیست؟! ولی اگر دارید از "حق" صحبت میکنید... اینکه میخواهید بفهمید این کاربر "حق فلان کار" را دارد یا نه... در نسخه Core از Claim هم میتوانید استفاده کنید...


...نمایش Name مربوط به Role یک کاربر...
همانطورکه عرض کردم کاربر یک Role ندارد...
اگر میخواهید عنوانی به فرد بدهید، بنظرم بهتر است یک فیلد جدا در جدول User برایش بگذارید (حتی میتوان Claim هم تعریف کرد ولی برای اینکار فیلد عادی بهتر است)
Role ها را بگذارید بابت تشخیص سطح دسترسی و اجازه ها و...


...یک Role را بگیریم و کاربرانی که فقط آن نقش را دارند جستجو کنیم ؟...
چون دارید از Identity استفاده میکنید، اغلب این دستورات قبلا نوشته شده.
مثلا تابع UserManager.GetUsersInRoleAsync همین کار فوق را انجام میدهد.
یا تابع UserManager.IsInRoleAsync مشخص میکند یک کاربر عضو فلان گروه است یا نه
و..
(البته این توابع را من در نسخه Core بررسی کردم ولی گمانم در نسخه های قبلی هم شبیه همین ها وجود داشته باشد)
البته باز هم یادآوری میکنم که درنسخه Core میتوان مفهوم Role را از مفهوم "حق و اجازه" متمایز کرد.

موفق باشید.

_H2_
27-07-2017, 14:22
سلام مجدد
از تصویر شما اول تاپیک تان کمی تعجب کردم، برای نسخه قدیم، چیزی را فراموش کرده بودم وشک داشتم...
نسخه 2015 را مجدد دانلود کردم هم مطمئن شدم تصویر شما صحیح است و هم مشابه GetUsersInRoleAsync را برایتان یافتم.

کافیست سطر یک Role را بدست آورید.
آنگاه خصیصه Users را خواهید داشت که شامل تمام کاربران عضو آن Role است.

مثلا اگر کلید جداولتان string است کدی شبیه این میشود

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

ali_i3
27-07-2017, 21:05
سلام مجدد
از تصویر شما اول تاپیک تان کمی تعجب کردم، برای نسخه قدیم، چیزی را فراموش کرده بودم وشک داشتم...
نسخه 2015 را مجدد دانلود کردم هم مطمئن شدم تصویر شما صحیح است و هم مشابه GetUsersInRoleAsync را برایتان یافتم.

کافیست سطر یک Role را بدست آورید.
آنگاه خصیصه Users را خواهید داشت که شامل تمام کاربران عضو آن Role است.

مثلا اگر کلید جداولتان string است کدی شبیه این میشود

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید



سلام مجدد
از تصویر شما اول تاپیک تان کمی تعجب کردم، برای نسخه قدیم، چیزی را فراموش کرده بودم وشک داشتم...
نسخه 2015 را مجدد دانلود کردم هم مطمئن شدم تصویر شما صحیح است و هم مشابه GetUsersInRoleAsync را برایتان یافتم.

کافیست سطر یک Role را بدست آورید.
آنگاه خصیصه Users را خواهید داشت که شامل تمام کاربران عضو آن Role است.

مثلا اگر کلید جداولتان string است کدی شبیه این میشود

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

ممنونم بابت وقتی که میزارید و جواد میدید , من نوع فیلد رو همون String گذاشتم.
هنوز مورد جستجو رو ننوشتم امیداورم که این کد جواب بده.

در مورد ارتباط چند به چند که توضیح دادید در پروژه ای که در حال تکمیلش هستم نیاز نشده که از ارتباط چند به چند یا پیچیتری برای کاربران استفاده کنم و البته شاید دلیل اینه که با وجود مطالب زیادی که راجب Identity خوندم ولی هنوز بخوبی درکش نکردم (این تنها موردی هست که تو کل مباحثی که در Asp.net Mvc باهاش مواجه شدم بخوبی یادش نگرفتم )و البته خود این شاید یه دلیل این باشه که من از روش Data Base First استفاده میکنم و و بدلیل Code First کار نکردن , درک عمیقی از Code First ندارم .)

در پروژه جاری بنده که یک فروشگاه اینترنتی هست بنظر من برای هر کاربر فقط داشتن یک Role کفایت میکنه , چون وقتی یک کاربر مثلا نقش PrimaryAdmin (به معنی مدیر کل سایت) رو داره قطعا به تمام قسمت های سایت دسترسی رو خواهد داشت و دیگه نیازی نیست Role های Assistant یا Member یا هر Role سطح پایینتری رو بهش بدیم.

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

[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

_H2_
27-07-2017, 23:38
سلام

... ارتباط چند به چند ...
ارتباط چند به چند یک بحث طراحی دیتابیس است و طراحی و قوانین "نرمال" است.


...برای هر کاربر فقط داشتن یک Role کفایت میکنه...
حالا کمی امکانات بیشتر که ضرر ندارد!


...اگر بخوام در هر سطری که اطلاعات یک کاربر نمایش می یابد نام Role (یا role ها) را هم نشان دهیم , چه کدی باید نوشت ؟
میتوانید Role های هر کاربر را (که شما می گویید اغلب یک Role است) با ویرگولی جدا کرده و نمایش دهید.
البته میدانید که استخراج Role هایی که یک نفر دارد، برعکس سوال قبلی تان است.
(استخراج User هایی که یک Role را دارند)

کدی حدودی و شبیه این احتمالا کار میکند... باز خودتان امتحان کنید، کد را همینجا نوشتم...

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

ali_i3
28-07-2017, 13:06
کدی حدودی و شبیه این احتمالا کار میکند... باز خودتان امتحان کنید، کد را همینجا نوشتم...

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
منظور از app_user_manager چیه ؟ چون به این شکل که نمیشناسدش ؟
و GetRoles هم بصورت پیشفرض در Identity 2.1 تعریف شده ؟

_H2_
28-07-2017, 14:53
سلام

منظور از app_user_manager چیه ؟
کلاس و اشیایی اصلی مانند UserManager و RoleManager و UserStore و RoleStore و IdentityDbContext و... از اجزای اصلی AspNet Identity هستند که در کار با AspNet Identity معمولا برای افراد شناخته شده هستند.

مشخص است که نام app_user_manager یک نماد است.
شما باید آن را با ارجاع از UserManager برنامه خودتان پر کنید.
وقتی از Identity در MVC استفاده میکنید گمانم معمولا یک کلاس UserManager برای شما ایجاد میشود.
(الآن من پروژه ای تحت نسخه قدیم Identity ندارم ...)

در کدتان جستجو کنید، دقت کنید، بعید نیست یک کلاس به نام ApplicationUserManager در کدتان داشته باشید که وراثت Microsoft.AspNet.Identity.UserManager است ، شما میتوانید از این کلاس استفاده و مثلا new کنید...

اگر مشکل تان حل نشد، یک تصویر از فایل های پروژه تان برایم بفرستید، ببینم چه کلاس هایی دارید.

(نماد شی app_user_manager یعنی هرطور در معماری تان دیده اید ،پرش کنید، مثلاحالا بعید میدانم ولی اگر از معماری DI استفاده میکنید این باید بجای new مستقیم باید از مخزن تامین شود...)


GetRoles هم بصورت پیشفرض در Identity 2.1 تعریف شده ؟
توابع اصلی عضو UserManager بیشتر Async هستند.
مثلا درهمین مورد تابع غیرهمزمان GetRolesAsync عضواصلی UserManager است.

توابع عادی (غیر Async) عضواصلی UserManager نیستند.
این توابع عادی بصورت "توابع الحاقی (Extensions)" در UserManagerExtensions قرار دارند.
برای استفاده ساده از توابع الحاقی باید namespace آنها using شود، سپس مانند توابع عضو قابل استفاده هستند.
(درواقع مایکروسافت پیشفرض کار را روی اجرا در Thread مستقل و Async گذاشته، توابع الحاقی فوق هم Thread را ساخته و منتظر پایانش می مانند و سپس جواب را پس میدهند!!! یکجورهایی برنامه نویس را مجبور میکنند از معماری Async بیشتر استفاده کند.)


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

دقت کنید در کدهای Razor باید قبل از using نماد @ هم بیاید.
یا میتوانید این using را بطور کلی در web.config برای کل پروژه اعمال کنید.

حالا تلاشی بکنید، انشاا... رفع شود، نشد هم نگران نباشید، با کمی اشناییت بیشتر با زبان و ساختار و... حل میشود
موفق باشید.

ali_i3
29-07-2017, 10:30
حالا تلاشی بکنید، انشاا... رفع شود، نشد هم نگران نباشید، با کمی اشناییت بیشتر با زبان و ساختار و... حل میشود
موفق باشید.


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

[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
سوال من برای موقعی هست که لیست تمامی کاربران را نمایش میدهیم :
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

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

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

_H2_
29-07-2017, 21:58
سلام


با این کلاس UserManager و تابع GetRolesAsync آشنایی دارم

خوب خیلی خوب است، پس مشکلی وجود ندارد.



در سمت View چه کدی را نوشت؟

از نظر کدنویسی CSharp تفاوتی بین توانایی انجام کارها در Controller یا View وجود ندارد.
همانطورکه Controller ما یک کلاس است و وراثت System.Web.Mvc.Controller است...
View ما هم یک کلاس است و وراثت System.Web.Mvc.WebViewPage
کدهای بظاهر html داخل View به متدهای Write تبدیل و کامپایل میشود ;("...Write("...HTML

اگر بحث نظم و ترتیب و لایه بندی کارها نبود، شما میتوانستید و میتوانید (!) کدهای Control را در View هم بنویسید...

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگر به کدهای فوق دقت بیشتری کنید، متوجه میشوید، محدودیت خاصی در توانایی کدنویسی شما در بخش View وجود ندارد.
هرکاری در Controller انجام میدهید را میتوانید اینجا هم انجام دهید.

میتوانید همان کدی را که در Controller برای شما UserManager را میسازد در View هم بنویسید.
میتوانید UserManager را در Controller در یک ViewBag بریزید تا در View هم داشته باشیدش
و...و...

مثلا

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
امیدوارم با اطلاعات فوق بتوانید مشکل تان را حل کنید.
موفق باشید.

_H2_
29-07-2017, 22:13
البته بجز جواب مفصلی که در پست قبلی دادم...
در شرایط مختلف برنامه نویس میتواند از راه های گوناگونی به جواب خودش برسد.
مثلا اگر نوع Model.Users شما در View تات (تصویر پست پنجم تان) ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]) از IdentityUser یا ApplicationUser باشد... یعنی با خود usermanager استخراجش کرده باشید.... در این صورت این اشیا خودشان خصیصه Roles دارند که شامل تمامی نقش های آن کاربر میشود...

چون کد را ندیده ام قطعی نمیتوانم نظر دهم، ولی شاید کد زیر هم برای td آخرتان کار کند.
(بدون نیاز مجدد به شی app_user_manager)

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

ali_i3
30-07-2017, 10:39
البته بجز جواب مفصلی که در پست قبلی دادم...
در شرایط مختلف برنامه نویس میتواند از راه های گوناگونی به جواب خودش برسد.
مثلا اگر نوع Model.Users شما در View تات (تصویر پست پنجم تان) ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]) از IdentityUser یا ApplicationUser باشد... یعنی با خود usermanager استخراجش کرده باشید.... در این صورت این اشیا خودشان خصیصه Roles دارند که شامل تمامی نقش های آن کاربر میشود...

چون کد را ندیده ام قطعی نمیتوانم نظر دهم، ولی شاید کد زیر هم برای td آخرتان کار کند.
(بدون نیاز مجدد به شی app_user_manager)

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

آره همینه در تصوریر زیر مشخصه :
منتهی این کد الان نوشتید واضحه که Id مربوط به Role ها رو نشون میده نه Name ها رو !

[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

نهایتا مشکل با نوشتن خط 17 در تصوریر بالا
و کد زیر در کنترولر :
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
و همون کدی که در پست ها اولی گفتیددر View
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مشکل حل شد.
خداییش نه کار سختی بود و نه نیاز به نوشتن N خط کد بود و نه نیاز به دونستن مباحث خیلی پیچیده و بی ربط - کلش 3 خط کد بود.

بازهم ممنون از وقتی که گذاشتید .