شروع دوره پایتون از پنجشنبه 1 خرداد ، مقدماتی تا پیشرفته، بدون پیش نیاز شروع دوره پایتون از پنجشنبه 1 خرداد ، مقدماتی تا پیشرفته، بدون پیش نیاز
🎯 ثبت نام
بستن تبلیغات
تسلط کامل بر سی‌شارپ با یک دوره پروژه‌محور

یادگیری سی شارپ از مفاهیم پایه تا پروژه محور: شی‌گرایی، کار با SQL و LINQ، ORMها (Entity Framework)، ساخت پروژه مدیریت رستوران با گزارشات حرفه‌ای و امکانات کامل!

مشاهده بیشتر
تسلط جامع بر MVC Core برای توسعه وب حرفه‌ای

یادگیری MVC Core از مبانی تا پیشرفته: شی‌گرایی، Routing، Entity Framework، امنیت، تست یونیت، Razor، Ajax، و پروژه‌های کاربردی! یک دوره کامل برای تسلط بر توسعه وب با ASP.NET Core. به صورت حضوری و آنلاین!

مشاهده بیشتر

نحوه ایجاد تایید هویت در ASP.NET MVC 5

تایید هویت در ASP.NET MVC 5

در ASP.NET MVC 5 به ویژگی های احراز هویت و اختیاردهی (authentication and authorization) فریمورک basic MVC پرداخته ام، و توضیح داده ام که زمانی که کتاب Pro ASP.NET MVC 5 Platform من چاپ شود، Apress قبول کرده است که فصل های مربوط به این کتاب را توزیع کند.
سه فصلی که در ادامه می آیند به معرفی ورژن 2.0 از هویت ASP.NET می پردازند. این ویژگی پلتفرم جدیدی در مایکروسافت بوده و کار آن مدیریت کاربران است. در این فصول به چگونگی ایجاد و نصب یک هویت بیسیک، چگونگی احراز هویت و اختیاردهی کاربران و چگونگی اعمال اختیاردهی مبتنی بر درخواست (claims-based authorization) در برنامه هایتان خواهیم پرداخت. همچنین چگونگی محول کردن احراز هویت به اشخاص ثالث را نیز تبین می کنم. برای احراز هویت کاربران می توان از حساب های مایکروسافت، توییتر و فیسبوک نیز استفاده کرد، هرچند که من در این فصول از گوگل استفاده کرده ام.
این فصول بدون هیچ تغییری از پلتفرم Pro ASP.NET MVC 5 گرفته شده اند. برای اینکه مثال های زده شده در این سه فصل را دنبال کنید، نیازی به کپی این کتاب ندارید. با این حال رفرنس فصل هایی که در اینجا به آن ها پرداخته نشده است، قید شده است. سورس کد نمونه پروژه ها را می توانید از www.apress.com/9781430265412 دانلود کنید.
امیدوارم این فصول برایتان مفید باشد و در تمامی پروژه های ASP.NET موفق باشید.

اصول مقدماتی Identity یا هویت

هویت، API جدیدی است که برای مدیریت کاربران در نرم افزارهای ASP.NET توسط مایکروسافت ارائه شده است. محور اصلی مدیریت کاربر در سال های اخیر عضویت در ASP.NET بوده است. این روش مدیریت کاربر در زمینه ی گزینه های طراحی ایرادهایی را از خود نشان داده است. با وجود اینکه این گزینه ها که در سال 2005 معرفی شدند معقول بودند، اما امروزه دیگر منسوخ شده اند. بزرگترین محدودیت این طرح جهت نگهداری داده ها این است که این رویکرد تنها در کنار SQL سرور جواب می دهد و بدون پیاده سازی مجدد تعداد زیادی از provider class ها توسعه دادن آن کار سختی است. این طرح به خودی خود بسیار پیچیده بود و نسبت به آن چیزی که باید باشد، کار پیاده سازی تغییرات را سخت تر می کرد.
مایکروسافت قبل از معرفی هویت در راستای بهبود عضویت قدم هایی را برداشته است. اولین قدم به عضویت ساده معروف بود که طی آن پیچیدگی این طرح کمتر شد، و شخصی سازی اطلاعات کاربر آسان تر شد. با این حال هنوز به یک مدل نسبی حافظه نیاز داشت. دومین قدم ASP.NET universal providers بود. که من برای راه اندازی حافظه ی session data ها در SQL سرور از آن استفاده کرده ام. مزیت تامین کننده های جهانی (universal providers) این است که آن ها برای ایجاد طرح پایگاه داده ای به صورت خودکار از ویژگی Entity Framework Code First استفاده می کنند. این ویژگی، این قابلیت را ایجاد کرده است که بتوان در موقعیت هایی که دسترسی به ابزار مدیریت طرح مانند Azure cloud service امکان پذیر نیست، پایگاه های داده ای را ایجاد کرد. با این حال با وجود بهتر شدن سیستم عضویت، مشکلات اساسی وابسته به داده های نسبی و شخصی سازی دشوار همچنان باقی مانده اند.
مایکروسافت برای حل این دو مشکل و جهت ارائه ی پلتفرم مدیریت کاربر به روزتر هویت را جایگزین عضویت کرد. همانطور که در فصل های 14 و 15 خواهید دید، هویت ASP.NET انعطاف پذیر و قابل توسعه بوده و در عین حال هنوز به بلوغ نرسیده است، و ویژگی هایی که از نظر شما پیش پا افتاده اند ممکن است در سیستم های جا افتاده تر مشکل آفرین و زمانبر باشند.
مایکروسافت بابت انعطاف پذیر نبودن عضویت بهای زیادی پرداخت کرده است و هویت را آنقدر باز و انعطاف پذیر ایجاد کرده است که به هر صورتی که هست می توان از آن استفاده کرد؛البته تا زمانی که شما زمان و انرژی پیاده سازی چیزهای مورد نیاز خود را داشته باشید.
در این فصل به تبیین فرآیند راه اندازی هویت ASP.NET و ایجاد ابزار ساده تری برای مدیریت کاربر می پردازیم. به گونه ای که بتوان با استفاده از این ابزار، تک تک حساب های کاربری که در یک پایگاه داده ای ذخیره شده اند را مدیریت کرد.
هویت ASP.NET از انواع دیگر حساب های کاربری مانند حساب هایی که با استفاده از دایرکتوری فعال ذخیره شده اند، پشتیبانی می کند. اما با توجه به اینکه این نوع از حساب ها خارج از شرکت ها کاربرد زیادی ندارند (پیاده سازی Active Directive آنقدری پیچیده است که ارائه ی مثال هایی کلی و مفید برای من سخت است)، به آن ها نمی پردازیم.
در فصل 14 به شما نشان خواهم داد که چگونه با استفاده از این حساب های کاربری احراز هویت و اختیاردهی را انجام دهید. همچنین در فصل 15 به شما نشان می دهم که چگونه پا را از اصول اولیه فراتر گذاشته و تکنیک های پیچیده ای را اعمال کنید. در جدول زیر (1-13) چکیده ی این فصل ارائه شده است.


تیتر
مساله
راهکار
4-1
راه اندازی هویت ASP.NET
اضافه کردن بسته های نرم افزاری و تعریف کردن رشته ای اتصالی و یک استارت کلاس OWIN در فایل Web.config
8-5
آماده شدن برای استفاده از هویت ASP.NET
ایجاد کلاس هایی که بیانگر کاربر، مدیر کاربر، زمینه ی پایگاه داده ای و استارت کلاس OWIN باشد.
9 و 10
برشمارش حساب های کاربری
استفاده از مشخصه ی Users تعریف شده توسط کلاس user manager
13-11
ایجاد حساب های کاربری
استفاده از متد CreateAsync تعریف شده توسط کلاس user manager
16-14
اجبار مقررات رمز عبور
تنظیم مشخصه ی PasswordValidatorتعریف شده توسط کلاس user manager
یا با استفاده از کلاس پیش فرض PasswordValidator و یا با استفاده از استخراج اختصاصی
19-17
تایید صحت حساب های کاربری جدید
تنظیم مشخصه ی UserValidatorتعریف شده توسط کلاس user manager
یا با استفاده از کلاس پیش فرض UserValidatorو یا با استفاده از استخراج اختصاصی
22-20
پاک کردن حساب های کاربری
استفاده از متد DeleteAsyncتعریف شده توسط کلاس user manager
24-23
اصلاح حساب های کاربری
استفاده از متد UpdateAsyncتعریف شده توسط کلاس user manager

آماده سازی نمونه پروژه

در این فصل پروژه ای به نام Users را ایجاد کرده ام و به دنبال آن در کل این کتاب از مراحل یکسانی استفاده کرده ام. قالب Empty را انتخاب کرده ام و تیک گزینه ی اضافه کردن فولدرها و رفرنس های مورد نیاز یک برنامه ی MVC را زده ام. در این فصل برای سبک دهی به view ها از Bootstrap استفاده خواهیم کرد. به همین دلیل برای دانلود و نصب بسته ی نرم افزاری NuGet دستور زیر را در کنسول Visual Studio Package Manager وارد کرده و دکمه ی اینتر را فشار می دهیم.

Install-Package -version 3.0.3 bootstrap

در ادامه Home controller ای را ایجاده کرده ام که در مثال های به کاررفته بیشترین توجه را به خود معطوف کرده است. تعریف این controller در تیتر 1-13 نشان داده شده است. من برای توصیف جزئیات داده ها و حساب های کاربری از این controller استفاده خواهم کرد. و متد Index action دیکشنری ای از مقادیر را از طریق متد view به ویوی پیش فرض می دهد.

using System.Web.Mvc;
using System.Collections.Generic; namespace Users.Controllers {
    public class HomeController : Controller {
        public ActionResult Index() { Dictionary< string, object > data
        = new Dictionary< string, object >(); data.Add("Placeholder", "Placeholder"); return View(data);
        }
    }
}

با کلیک راست کردن بر روی متد Index action و انتخاب کردن Add View از منوی باز شده یک View را ایجاد کرده ام. اسم view را Index گذاشته و Template را به صورت Empty (بدون مدل) تنظیم کرده ام. برخلاف فصل های قبلی در این فصل می خواهم از یک layout مرسوم استفاده کنم. به همین دلیل تیک گزینه ی Use a Layout Page را زده ام. زمانی که بر روی دکمه ی Add کلیک کردم،
Visual Studio فایل های Views/Shared/_Layout.cshtml و Views/Home/Index.cshtml را ایجاد کرد. در تیتر 2-13 محتوای داخل فایل Layout.cshtml_ نشان داده شدن است.

< !DOCTYPE html >
< html >
< head >
    < meta name="viewport" content="width=device-width" / >
    < title >@ViewBag.Title< /title >
    < link href="~/Content/bootstrap.min.css" rel="stylesheet" / >
    < link href="~/Content/bootstrap-theme.min.css" rel="stylesheet" / >
    < style >
        .container { padding-top: 10px; }
        .validation-summary-errors { color: #f00; }
    < /style >
< /head >
< body class="container" >
    < div class="container" >
    @RenderBody()
    < /div >
< /body >
< /html >

@{
ViewBag.Title = "Index";
}
< div class="panel panel-primary" >
    < div class="panel-heading" >User Details< /div >
    < table class="table table-striped" >
        @foreach (string key in Model.Keys) {
            < tr >
                < th >@key< /th >
                < td >@Model[key]< /td >
            < /tr >
        }
    < /table >
< /div >

برای آنکه تست کنید که این نمونه نرم افزار درست کار می کند، به منوی Visual Studio Debug رفته و Start Debugging را انتخاب کنید و در نهایت به /Home/IndexURL بروید. نتیجه را می توانید در شکل 1-13 مشاهده کنید.


آموزش احراز هویت در ASP.Net MVC 5

راه اندازی هویت ASP.NET

هویت باعث می شود که اغلب برنامه نویسان ASP.NET برای اولین بار در معرض Open Web Interface for .NET (OWIN) قرار بگیرند. OWIN لایه ی انتزاعی بوده که یک برنامه ی تحت وب را از محیطی که آن را میزبانی می کند، جدا می کند. روند کار به این صورت است که این لایه باعث می شود نوآوری بیشتری در فناوری ASP.NET ایجاد شده و انعطاف پذیری محیط هایی که می توانند میزبان برنامه های ASP.NET باشند افزایش پیدا کند همچنین زیرساخت سرور را سبک تر می کند.
OWIN یک استاندارد باز است. (برای مطالعه در این باره به این لینک مراجعه کنید http://owin.org/spec/owin-1.0.0.html).
مایکروسافت برای پیاده سازی استاندارد OWIN پروژه ی Katana و مجموعه ای از کامپوننت هایی را ایجاد کرده است که برنامه های تحت وب برای کار کردن به آن ها نیاز دارند. چیزی که برای مایکروسافت جذاب است این است که OWIN و Katana فناوری ASP.NET را از دیگر بخش های باقی مانده ی فریمورک .NET جدا می کند. این کار باعث می شود بیشتر بتوان در برنامه تغییرات اعمال کرد.
برنامه نویسان OWIN به جای آنکه کل پلتفرم را مانند چیزی که در ASP.NET اتفاق می افتد انتخاب کنند، سرویس هایی را مورد استفاده قرار می دهند که نرم افزارشان به آن ها نیاز دارد. سرویس های انفرادی که در واژگان تخصصی OWIN به middleware معروف هستند، را می توان طی نرخ های متفاوتی توسعه داد و برنامه نویسان قادر خواهند بود تا به جای آنکه محدود به پیاده سازی مایکروسافت باشند، به ازای سرویس های مختلف بین تامین کننده ها حق انتخاب داشته باشند.
دلایل مختلفی وجود دارد برای آنکه به مسیر کلی ای که OWIN و Katana در حال حرکت در آن هستند علاقه مند شوید.اما این دو روزهای اولیه ی خود را سپری می کنند و برای آنکه به پلتفرم کاملی برای نرم افزارهای ASP.NET تبدیل شوند، اندکی زمان نیاز دارند. تا به این لحظه که من در حال نوشتن این کتاب هستم، این امکان وجود دارد تا بدون نیاز به System.Webnamespace و یا IIS برای پردازش درخواست ها نرم افزارهای SignalR و API های تحت وب را بسازیم. اما این همه ی ماجرا نیست. فریمورک MVC به پلتفرم استاندارد ASP.NET نیاز دارد، و همچنان تا مدتی به آن نیاز خواهد داشت.
پلتفرم ASP.NET و IIS در حال از بین رفتن نیستند. مایکروسافت به صراحت اعلام کرده است که یکی از جذاب ترین ویژگی های OWIN را یافته است. به گونه ای که به کمک آن می تواند به برنامه نویسان انعطاف پذیری بیشتری ارائه کند، که در طی آن کامپوننت های middleware توسط IIS میزبانی شده و پروژه ی Katana تا به همین لحظه از namespace های System.Web پشتیبانی می کند. OWIN و Katana آخر خط ASP.NET نیستند، بلکه این دو انقلابی را رقم زده اند که مایکروسافت به کمک آن ها انعطاف پذیری کاربران جهت اسمبل و اجرا کردن نرمافزارهای ASP.NET را افزایش داده است.

نکته :

هویت اولین و اصلی ترین کامپوننت ASP.NET است که باید به عنوان میان افزار OWIN تحویل داده شود.اما آخرین کامپوننت نیست.

مایکروسافت تضمین کرده است که آخرین ورژن های Web API و SignalR به namespace های System.Web وابسته نیستند، و این یعنی هر کامپوننتی که برای به کار رفتن در مجموعه فناوری های ASP.NET لحاظ شده اند، باید از طریق OWIN تحویل داده شوند. در کتاب Expert ASP.NET Web API 2 for MVC Developers خودم، مفصل تر به OWIN پرداخته ام. این کتاب در سال 2014 توسط Apress منتشر خواهد شد.
OWIN و Katana تا مدتی تاثیر چشمگیری بر برنامه نویسان MVC نخواهند گذاشت.اما تا همین لحظه تغییراتی را بر فریمورک MVC اعمال کرده اند.یکی از این تغییرات این است که هویت ASP.NET به عنوان یک کامپوننت میان افزار OWIN پیاده سازی می شود. این حالت چندان ایده آل نیست زیرا این معنی را می دهد که برای استفاده از هویت برنامه های فریمورک MVC حتما باید تکنیک های پلتفرم سنتی OWIN و ASP.NET را با یکدیگر ترکیب کنند.
اما بعد از اینکه اصول اولیه را متوجه شوید و بدانید که چگونه باید OWIN را راه اندازی کنید (که من در بخش های بعدی توضیح خواهم داد)، دیگر این کار چندان سخت نخواهد بود.

ایجاد دیتابیس برای هویت ASP.NET

وابستگی هویت ASP.NET به طرح SQL سرور، مشابه به وابستگی عضویت به این طرح نیست. بلکه حافظه ی نسبی همچنان گزینه ی پیش فرض و البته ساده ترین گزینه است. من نیز در این فصل از همین گزینه استفاده خواهم کرد. هرچند که جنبش نه به SQL در سال های اخیر افزایش پیدا کرده است، اما پایگاه های داده ای نسبی همچنان انتخاب اصلی برای ذخیره سازی داده بوده و درک آن ها برای اغلب تیم های برنامه نویسی ساده تر است.
هویت ASP.NET برای ایجاد خودکار طرح خود از ویژگی Entity Framework Code First بهره می برد. اما من همچنان باید دیتابیس را در این طرح ایجاد کنم و درست مانند زمانی که دیتابیس را برای session state data ایجاد کردم، داده های کاربر نیز ایجاد خواهد شد. (تامین کننده ی جهانی که من برای مدیریت دیتابیس استفاده کردم نیز از ویژگی Code First استفاده می کند.)

نکته :

برای استفاده از هویت ASP.NET نیازی به دانستن چگونگی کارکرد Entity Framework و یا ویژگی Code First نیست.


مانند فصل 10 من برای ایجاد دیتابیس خودم از ویژگی localdb استفاده خواهم کرد. جهت یادآوری localdb در ویژوال استودیو وجود داشته و ورژن کوتاه شده ای از SQL سرور است که این امکان را به برنامه نویسان می دهد تا به راحتی پایگاه های داده ای را ایجاد و با آن کار کنند.
SQL Server Object Explorer را از منوی View ویژوال استودیو انتخاب کنید و بعد از باز شدن پنجره بر روی شیء SQL سرور کلیک راست کنید. مطابق با شکل 2-13 از منوی باز شده Add SQL Server را انتخاب کنید.


آموزش احراز هویت در ASP.Net MVC 5

بعد از انجام این کار ویژوال استودیو جمله ی Connect to Server را نمایش می دهد. اسم سرور را (localdb)\v11.0 بگذارید، گزینه ی Windows Authentication را انتخاب کنید و بر روی دکمه ی Connect کلیک کنید. بعد از انجام این کار ارتباط با پایگاه داده برقرار شده و در پنجره ی SQL Server Object Explorer نمایش داده می شود. شیء ایجاد شده ی جدید را گسترش دهید، بر روی Databases کلیک راست کنید و از پنجره ی باز شده Add New Database را انتخاب کنید .


آموزش احراز هویت در ASP.Net MVC 5

اسم دیتابیس را IdentityDb بگذارید، Location value این دیتابیس را بدون تغییر رها کنید و برای ایجاد آن بر روی دکمه OK کلیک کنید. دیتابیس جدید در بخش دیتابیس های SQL connection در SQL Server Object Explorer نمایش داده می شود.


اضافه کردن بسته های نرم افزاری هویت

هویت به صورت بسته های نرم افزاری NuGet منتشر می شود. این بسته ها باعث می شوند نصب آن ها در هر پروژه ای آسان شود. دستورات زیر را در Package Manager Console وارد کنید :

Install-Package Microsoft.AspNet.Identity.EntityFramework –Version 2.0.0Install-Package Microsoft.AspNet.Identity.OWIN -Version 2.0.0
Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0

ویژوال استودیو می تواند با استفاده از API هویت پروژه هایی را ایجاد کند که توسط مدیریت حساب کاربری ژنریک پیکربندی شده اند. با انتخاب کردن قالب MVC طی ایجاد پروژه و قرار دادن گزینه ی Authentication بر روی Individual User Accounts می توانید قالب ها و کدها را اضافه کنید. به شخصه من از قالب ها استفاده نمی کنم. زیرا آن ها بیش از حد کلی و خسته کننده بوده و ترجیح می دهم به صورت مستقیم محتوا و پیکربندی پروژه های خودم را کنترل کنم. به شما هم همین توصیه را می کنم. نه صرفا به این خاطر که به درک بهتری از کارکرد ویژگی های مهم برسید، بلکه نگاه کردن به قالب ها از این زاویه که متوجه شوید کارهای معمولی چگونه انجام می شوند نیز می تواند جالب توجه باشد.


به روز رسانی فایل Web.config

برای آنکه فایل Web.config برای پروژه ای از هویت ASP.NET آماده شود، دو تغییر را باید اعمال کرد. اولین تغییر رشته ی اتصالی است که وظیفه ی آن توصیف دیتابیسی است که من در بخش قبل ایجاد کردم. دومین تغییر تعریف تنظیمات برنامه ای است که کار آن نامگذاری کلاسی است که میان افزار OWIN را مقدار دهی اولیه می کند. این میان افزار در پیکربندی هویت کاربرد دارد. در تیتر 4-13 تغییراتی که من بر روی فایل Web.config ایجاد کرده ام نشان داده شده است. (در فصل 9 چگونگی کارکرد رشته های اتصالی و application settings (تنظیمات برنامه) را توضیح داده ام.)

< ?xml version="1.0" encoding="utf-8"? >
< configuration >
< configSections >
< section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" / >
< /configSections >
< connectionStrings >
< add name="IdentityDb" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)\v11.0;Initial
Catalog=IdentityDb;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False; MultipleActiveResultSets=True"/ >
< /connectionStrings >
< appSettings >
< add key="webpages:Version" value="3.0.0.0" / >
< add key="webpages:Enabled" value="false" / >
< add key="ClientValidationEnabled" value="true" / >
< add key="UnobtrusiveJavaScriptEnabled" value="true" / >
< add key="owin:AppStartup" value="Users.IdentityConfig" / >
< /appSettings >
< system.web >
< compilation debug="true" targetFramework="4.5.1" / >
< httpRuntime targetFramework="4.5.1" / >
< /system.web >
< entityFramework >
< defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory,
EntityFramework" >
< parameters >
< parameter value="v11.0" / >
< /parameters >
< /defaultConnectionFactory >
< providers >
< provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices,EntityFramework.SqlServer" / >
< /providers >
< /entityFramework >
< /configuration >
تذکر

حتما مقدار connectionString را در یک خط قرار دهید. من صرفا به این خاطر که تیتر در صفحه جا شود، آن را در چند خط نوشتم. اما ASP.NET از شما انتظار یک رشته ی پیوسته و تک خطی را دارد. برای اطمینان بیشتر سورس کدی که به همراه این کتاب ارائه شده است و به صورت رایگان در وبسایت www.apress.com موجود است را دانلود کنید.

OWIN مدل استارت آپ نرم افزاری مخصوص به خود را دارد که این امر جدای از کلاس نرم افزاری جهانی است که من در فصل 3 توضیح دادم. تنظیمات نرم افزار که اسم آن owin:AppStartup است وظیفه ی مشخص کردن کلاسی را بر عهده دارد که بعد از آنکه نرم افزار برای دریافت پیکربندی خود شروع به کار می کند، OWIN آن را نمونه سازی می کند.

نکته :

توجه داشته باشید که مشخصه ی MultipleActiveResultSets رشته ی اتصالی را بر روی true قرار داده ام. این کار باعث می شود نتایج حاصل از پرس و جوهای متعدد به صورت همزمان خوانده شوند. این قابلیت زمانی که بخواهم در فصل 14 به شما نشان دهم که چگونه بر اساس عضویت نقش محور (role membership) به action method ها دسترسی پیدا کنید، به من کمک خواهد کرد.


ایجاد کلاس های Entity Framework

اگر در گذشته در پروژه های خود از عضویت استفاده کرده باشید، از میزان زیاد آمادگی اولیه ی مورد نیاز برای هویت ASP.NET شگفت زده خواهید شد. هویت نبود توسعه پذیری عضویت را جبران کرده است. اما این کار بهایی دارد و بهای آن ایجاد مجموعه ای از کلاس های پیاده سازی است که Entity Framework برای مدیریت دیتابیس از آن ها استفاده می کند. در بخش زیر به شما نشان خواهم داد چگونه کلاس هایی را ایجاد کنید که Entity Framework برای ایفای نقش سیستم ذخیره سازی حافظه در هویت ASP.NET ، به آن ها نیاز دارد.


ایجاد کلاس کاربری

اولین کلاسی که میخواهیم تعریف کنیم کلاسی است که نمایانگر کاربر است. من این کلاس را user class نامیده ام. user class از IdentityUser مشتق شده که خود در Microsoft.AspNet.Identity.EntityFrameworknamespace تعریف می شود. IdentityUser به صورت پایه ای کاربر را ارائه می کند. و می توان آن را با اضافه کردن مشخصه هایی به کلاس مشتق شده توسعه داد. به این موضوع در فصل 15 می پردازیم. در جدول 2-13 مشخصه های پیش فرضی که IdentityUser آن ها را تعریف می کند، نشان داده شده است. من نیز در این فصل از همین مشخصه ها استفاده خواهم کرد.

نام مشخصه
توضیحات
Claims
مجموعه ای از درخواست ها را برای کاربر برگشت می دهد. به این مشخصه در فصل 15 می پردازم.
Email
آدرس ایمیل کاربر را برگشت می دهد.
Id
آیدی منحصر به فرد کاربر را برگشت می دهد.
Logins
مجموعه ای از لاگین ها را برای کاربر برگشت می دهد. به این مشخصه در فصل 15 می پردازم.
PasswordHash
رمز عبور کاربر را به صورت درهم برگشت می دهد. از این مشخصه در بخش "پیاده سازی ویژگی ویرایش" استفاده خواهم کرد.
Roles
مجموعه ای از نقش هایی را برگشت می دهد که کاربر به آن ها تعلق دارد. به این مشخصه در فصل 14 می پردازم.
PhoneNumber
شماره تلفن کاربر را برگشت می دهد.
SecurityStamp
مقداری را برگشت می دهد که زمانی که هویت کاربر تغییر می کند (مثلا زمانی که رمز عبور تغییر کند)، این مقدار نیز تغییر می کند.
UserName
نام کاربری را برگشت می دهد.

نکته :

کلاس های موجود در Microsoft.AspNet.Identity.EntityFrameworknamespace پیاده سازی عینی و مختص به Entity Framework مربوط به رابط های تعریف شده در Microsoft.AspNet.Identitynamespace هستند. برای مثال IdentityUser پیاده سازی رابط IUser محسوب می شود. من با کلاس های concrete کار میکنم زیرا برای ذخیره سازی اطلاعات کاربری ام در یک دیتابیس از Entity Framework استفاده می کنم. اما هرچه هویت ASP.NET جا افتاده تر شود، می توان انتظار داشت که پیاده سازی های جایگزین رابط هایی را ببینیم که از مکانیزم های متفاوتی برای ذخیره سازی اطلاعات استفاده می کنند (هرچند که اکثر پروژه ها هنوز از Entity Framework استفاده می کنند، زیرا متعلق به مایکروسافت است).


چیزی که در این لحظه حائز اهمیت است این است که کلاس IdentityUser امکان دسترسی را تنها به اطلاعات پایه ای کاربر فراهم می کند. برای مثال اسم، ایمیل، تلفن، پسورد hash ، عضویت های نقش محور و ... . اما اگر بخواهم اطلاعات بیشتری را در رابطه با کاربر ذخیره کنم، باید مشخصه هایی را به کلاسی اضافه کنم که از IdentityUser گرفته ام. این کلاس جهت ارائه ی کاربران در نرم افزار من کاربرد دارد. در فصل 15 بیشتر به این موضوع می پردازم. برای ایجاد کلاس کاربری برای نرم افزارم، فایل کلاسی به نام AppUserModels.cs را در فولدر Models ایجاد کرده ام، و از آن برای ساختن کلاس AppUser استفاده کرده ام. این کار در تیتر 5-13 نشان داده شده است.

using System;
using Microsoft.AspNet.Identity.EntityFramework;
namespace Users.Models {
public class AppUser : IdentityUser {
// additional properties will go here
}
}

فعلا کل کاری که باید انجام دهم همین است. هرچند که در فصل 15 زمانی که بخواهم به شما نشان دهم که چگونه مشخصه های داده های کاربری مختص به نرم افزار (application-specific user data properties) را اضافه کنید، به این کلاس برمی گردم.


ایجاد کلاس Database Context

مرحله ی بعد ایجاد یک زمینه ی دیتابیس برای Entity Framework است. این زمینه در کلاس AppUser کار می کند. با کمک این زمینه می توان ویژگی Code First را ایجاد کرد، طرح دیتابیس را مدیریت کرد و امکان دسترسی به داده هایی که این زمینه ذخیره می کند را فراهم کرد. کلاس کانتکس از IdentityDbContext مشتق می شود، که T کلاس کاربری (در این مثال AppUser) است. در این پروژه فولدری را به نام Infrastructure ایجاد کرده ام، و فایل کلاسی به نام AppIdentityDbContext.cs را به آن اضافه کرده ام. محتوای داخل این فایل را می توانید در تیتر 6-13 مشاهده کنید.

using System.Data.Entity;
using Microsoft.AspNet.Identity.EntityFramework; using Users.Models;
namespace Users.Infrastructure {
public class AppIdentityDbContext : IdentityDbContext { public AppIdentityDbContext() : base("IdentityDb") { }
static AppIdentityDbContext() { Database.SetInitializer(new IdentityDbInit());
}
public static AppIdentityDbContext Create() { return new AppIdentityDbContext();
}
}
public class IdentityDbInit
: DropCreateDatabaseIfModelChanges {
protected override void Seed(AppIdentityDbContext context) { PerformInitialSetup(context);
base.Seed(context);
}
public void PerformInitialSetup(AppIdentityDbContext context) {
// initial configuration will go here
}
}
}

constructor کلاس AppIdentityDbContext ، بیس خود را با اسم رشته ای اتصالی فراخوانی می کند که این رشته جهت متصل شدن به دیتابیس کاربرد دارد. رشته ی مذکور در این مثال IdentityDb است. به این صورت است که رشته ی اتصالی را که در تیتر 4-13 تعریف کردم به هویت ASP.NET مربوط می کند.
کلاس AppIdentityDbContext یک constructor استاتیک را نیز تعریف می کند. این constructor از متد Database.SetInitializer استفاده می کند تا کلاسی که در زمان ایجاد طرح از طریق ویژگی Entity Framework Code First دیتابیس را پیگردی می کند را تشخیص دهد. کلاسی که برای پیگردی در نظر گرفته ام IdentityDbInit نام دارد. به اندازه ی کافی کلاس ایجاد کرده ام که بتوان placeholder ای ایجاد کرد که در آینده با اضافه کردن عبارت هایی به متد PerformInitialSetup به کار پیگردی دیتابیس برگردم. چگونگی انجام پیگردی دیتابیس را در فصل 14 به شما خواهم آموخت.
در نهایت کلاس AppIdentityDbContext یک متد Create را تعریف می کند. به این صورت است که نمونه های کلاس زمانی که OWIN به آن ها نیاز داشته باشد، ایجاد می شوند. این کار با استفاده از کلاسی انجام می شود که من در بخش "ایجاد Start Class" به آن پرداخته ام.

نکته :

اگر نقش این کلاس ها از نظرتان مفهومی ندارد جای نگرانی نیست. اگر با Entity Framework آشنا نیستید، در این صورت به شما پیشنهاد می کنم که به آن به چشم جعبه ی سیاه هواپیما نگاه کنید. بعد از اینکه بلوک های اولیه را در جای خود قرار دهید (می توانید این کار را با کپی کردن بلوک هایی که نیاز دارید انجام دهید) دیگر به ندرت پیش می آید که نیازی به ویرایش آن ها داشته باشید.


ایجاد کلاس User Manager

یکی از مهمترین کلاس هایی که در هویت کاربرد دارد، user manager است. وظیفه ی این کلاس مدیریت نمونه های کلاس user است. این کلاس باید از UserManager مشتق شود، که T کلاس user است. کلاس UserManager مختص به Entity Framework نبوده و برای ایجاد و عملیاتی کردن داده های کاربر ویژگی های کلی تری را ارائه می کند. در جدول 3-13 متدها و مشخصه های اصلی تعریف شده توسط کلاس UserManager جهت مدیریت کاربران نشان داده شده است. مشخصه ها و متدهای دیگری نیز وجود دارد، اما به جای آنکه تمام آن ها را بیان کنم زمانی که بخواهم روش های مختلف مدیریت داده های کاربر را توضیح دهم، در متن به آن ها می پردازم.

نام
توضیحات
ChangePasswordAsync(id, old, new)
رمز عبور کاربر مشخص شده را تغییر می دهد.
CreateAsync(user)
کاربر جدیدی بدون رمز عبور ایجاد می کند. برای مشاهده ی مثال های این بخش به فصل 15 مراجعه کنید.
CreateAsync(user, pass)
کاربر جدیدی با رمز عبوری مشخص ایجاد می کند. به بخش "ایجاد کاربران" مراجعه کنید.
DeleteAsync(user)
کاربر مشخص شده را پاک می کند. به بخش "پیاده سازی ویژگی Delete" مراجعه کنید.
FindAsync(user, pass)
شیئی را پیدا می کند که بیانگر کاربر است و رمز عبور آن ها را احراز می کند. برای مطالعه ی جزئیات احراز هویت به فصل 14 مراجعه کنید.
FindByIdAsync(id)
شیء کاربر مربوط به ID مشخص شده را پیدا می کند. به بخش "پیاده سازی ویژگی Delete" مراجعه کنید.
FindByNameAsync(name)
شیء کاربر مربوط به اسم مشخص شده را پیدا می کند. از این متد در بخش "پیگردی دیتابیس" فصل 14 استفاده کرده ام.
UpdateAsync(user)
تغییرات اعمال شده بر روی شیء کاربر را به دیتابیس برمی گرداند. به بخش "پیاده سازی ویژگی Edit" مراجعه کنید.
Users
بر شمارشی از کاربران را برگشت می دهد. به بخش "برشمارش حساب های کاربری" مراجعه کنید.

نکته :

توجه داشته باشید که اسامی تمامی این متدها با Async تمام می شوند. دلیل این امر این است که تقریبا کل هویت ASP.NET از طریق ویژگی های برنامه نویسی ناهمگام C# پیاده سازی می شود. این یعنی عملیات ها به صورت همزمان اجرا شده و مانع فعالیت های دیگر نمی شوند. بعد از آنکه چگونگی ایجاد و مدیریت داده های کاربری را آموزش دهم، روش کارکرد این رویکرد را متوجه خواهید شد. تقریبا در هریک از متدهای Async متدهای گسترشی همگام نیز وجود دارند. در اغلب مثال ها من متدهای ناهمگام را ترجیح می دهم اما اگر نیاز داشته باشید که به صورت پشت سرهم عملیات های مرتبط متعددی را اجرا کنید، متدهای همگام نیز به همان اندازه می تواند مفید باشد. مثالی در رابطه با این موضوع در بخش "پیگردی دیتابیس" در فصل 14 ارائه کرده ام. کاربرد دیگر متدهای همگام برای زمانی است که بخواهید متدهای هویت را از داخل property getter ها و property setter ها فراخوانی کنید، که این کار را در فصل 15 انجام می دهم.


فایل کلاسی به نام AppUserManager.cs را به فولدر Infrastructure اضافه کرده و از آن جهت تعریف کلاس user manager (که اسم آن را AppUserManager گذاشته ام) استفاده کرده ام.

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin; using Users.Models;
namespace Users.Infrastructure {
public class AppUserManager : UserManager< AppUser > {
public AppUserManager(IUserStore< AppUser > store)
: base(store) {
}
public static AppUserManager Create( IdentityFactoryOptions< AppUserManager > options, IOwinContext context) {
AppIdentityDbContext db = context.Get< AppIdentityDbContext >(); AppUserManager manager = new AppUserManager(new UserStore< AppUser >(db));
return manager;
}
}
}

متد استاتیک Create زمانی که هویت به نمونه ای از AppUserManager نیاز داشته باشد، فراخوانی می شود. این اتفاق زمانی رخ می دهد که عملیات هایی را در داده های کاربری اجرا کنم (به این موضوع بعد از آنکه اجرای راه اندازی را تمام کنم می پردازم).
برای آنکه نمونه ای از کلاس AppUserManager ایجاد شود، به نمونه ای از UserStore< AppUser > نیاز دارم. کلاس UserStore< T > پیاده سازی Entity Framework رابط IUserStore< T > است، که این کلاس پیاده سازی مختص به ذخیره سازی حافظه ی متدهایی را ارائه می کند که توسط کلاس UserManager تعریف شده اند. برای آنکه UserStore< AppUser > ایجاد شود به نمونه ای از کلاس AppIdentityDbContext نیاز دارم، که مانند زیر از طریق OWIN این کار را انجام می دهم.

...
AppIdentityDbContext db = context.Get< AppIdentityDbContext >();
...

پیاده سازی IOwinContext که به عنوان آرگومانی به متد Create داده شده است، متد get ای را تعریف می کند که اصطلاحا generically typed بوده و نمونه هایی از اشیائی را برگشت می دهد که این اشیاء در OWIN start class ثبت شده بودند. در بخش زیر به این موضوع می پردازم.


ایجاد Start Class

به آخرین بخشی که باید بپردازم تا پرونده ی هویت ASP.NET بسته شود، start class است. در تیتر 4-13 تنظیمات نرم افزاری را تعریف کرده ام که مانند زیر برای OWIN یک کلاس پیکربندی را مشخص کرده است.

...
< add key="owin:AppStartup" value="Users.IdentityConfig" / >
...

OWIN مستقل از ASP.NET ظهور یافته و قوانین مخصوص به خود را دارد. یکی از این قوانین این است که کلاسی وجود دارد که برای بارگیری و پیکربندی میان افزار، همچنین اجرای تمامی کارهای پیکربندی که مورد نیاز است نمونه سازی می شود. به صورت پیش فرض این کلاس Start نامیده می شود و در global namespace تعریف می شود. این کلاس شامل متدی به نام Configuration است که این متد توسط زیرساخت OWIN فراخوانی می شود و پیاده سازی رابط Owin.IAppBuilder را عبور می دهد. این مورد از راه اندازی میان افزاری پشتیبانی می کند که نرم افزارها نیاز دارند. کلاس Start معمولا به صورت یک کلاس جزئی و به همراه دیگر فایل های کلاس مختص به هر نوع از میان افزارهای مورد استفاده، تعریف می شود.
من بدون هیچ محدودیتی از این قانون صرف نظر می کنم. زیرا هویت تنها میان افزار OWIN ای است که در نرم افزار مبتنی بر فریمورک MVC استفاده می کنم. ترجیح من این است که برای تعریف کردن تنها یک کلاس در بالاترین سطح namespace نرم افزار، از تنظیمات نرم افزار در فایل Web.config استفاده کنم. در همین راستا فایل کلاسی به نام IdentityConfig.cs را به فولدر App_Start اضافه کردم و برای تعریف کلاس نشان داده شده در تیتر 8-13 از آن استفاده کرده ام. این همان کلاسی است که در فولدر Web.config مشخص کرده ام

using Microsoft.AspNet.Identity; using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies; using Owin;
using Users.Infrastructure;
namespace Users {
public class IdentityConfig {
public void Configuration(IAppBuilder app) {
app.CreatePerOwinContext< AppIdentityDbContext >(AppIdentityDbContext.Create); app.CreatePerOwinContext< AppUserManager >(AppUserManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"),
});
}
}
}

رابط IAppBuilder توسط تعدادی از متدهای گسترشی تعریف شده در کلاس ها در Owinnamespace تکمیل می شود. متد CreatePerOwinContext نمونه ای جدید از AppUserManager و کلاس های AppIdentityDbContext را به ازای هر یک از درخواست ها ایجاد می کند. با این روش تضمین می شود که هر یک از درخواست ها به خوبی به داده های هویت ASP.NET دسترسی داشته و نیازی به نگرانی در رابطه با همگام سازی یا کش شدن ضعیف داده های دیتابیس وجود ندارد.
متد UseCookieAuthentication به هویت ASP.NET می گوید که برای کاربران احراز هویت شده (identity authenticated users) از cookie استفاده کند، به گونه ای که Option ها از طریق کلاس CookieAuthenticationOptionsclass مشخص می شوند. بخش مهم در اینجا مشخصه ی LoginPath است. این مشخصه آدرس URL ای را مشخص می کند که وقتی کلاینت ها بدون احراز هویت در خواست محتوا کنند، به این آدرس هدایت شوند. من برای این آدرس /Account/Login را مشخص کرده ام، و برای مدیریت هدایت کاربران controller ای را در فصل 14 ایجاد خواهم کرد.


استفاده از هویت ASP.NET

حالا که اصول اولیه از سر راه برداشته شده اند، می توانم برای مدیریت بهتر کاربران در نمونه نرم افزار خود از هویت ASP.NET استفاده کنم. در بخش هایی که در ادامه می آیند، به چگونگی استفاده از API هویت جهت ایجاد ابزارهای مدیریتی می پردازم، و به کمک این API به صورت متمرکز کاربران را مدیریت خواهم کرد. جدول 4-13 هویت ASP.NET را به صورت ساده تری بیان کرده است.

پرسش
پاسخ
هویت ASP.NET چیست؟
API ای است که در مدیریت داده های کاربران و انجام احراز هویت و اختیاردهی کاربرد دارد.
هویت ASP.NET چه اهمیتی دارد؟
کاربران برای آن که بتوانند به ویژگی ها و محتواهای داخل نرم افزارها دسترسی داشته باشند، باید حساب کاربری ایجاد کنند و اطلاعات محرمانه ی خود را در آن وارد کنند. هویت ASP.NET انجام این کارها را آسان کرده است. چگونه می توان از آن توسط فریم هویت ASP.NET به صورت مستقیم توسط فریمورک MVC استفاده نمی شود بلکه از طریق ویژگی های احراز هویت MVC استاندارد ورک MVC استفاده کرد؟ یکپارچه سازی می شود.

برشمارش حساب های کاربری

ابزارهای مدیریت متمرکز کاربر تقریبا در تمامی نرم افزارها حتی آن دست از نرم افزارهایی که به کاربران اجازه ی ایجاد و مدیریت حساب های کاربری خود را می دهند مفید هستند. مثلا همیشه کاربرانی وجود دارند که به اقتضای نیاز خود باید تعداد زیادی حساب کاربری داشته باشند و یا مشکلات پشتیبانی ای که نیاز به نظارت و اصلاح داده های کاربر دارند. از نظر این فصل ابزارهای مدیریتی مفید هستند زیرا این ابزارها بسیاری از توابع مدیریتی پایه ای کاربران را در تعداد اندکی از کلاس ها ترکیب می کنند. این مثال، نمونه مفیدی جهت نشان دادن ویژگی های بنیادی هویت ASP.NET می تواند باشد.
من این کار را با افزودن controller ای در پروژه ی خود به نام Admin آغاز کرده ام. این controller را در تیتر 9-13 نشان داده ام و از آن جهت تعریف کارکرد مدیریتی کاربران خود استفاده خواهم کرد.

using System.Web; using System.Web.Mvc;
using Microsoft.AspNet.Identity.Owin; using Users.Infrastructure;
namespace Users.Controllers {
    public class AdminController : Controller {
        public ActionResult Index() { return View(UserManager.Users);
        }
    private AppUserManager UserManager { get {
            return HttpContext.GetOwinContext().GetUserManager< AppUserManager >();
            }
        }
    }
}

متد index action کاربرانی را برشمارش می کند که توسط سیستم Identity مدیریت می شوند. قطعا درست است که در حال حاضر کاربری وجود ندارد، اما در آینده نزدیک کاربرانی نیز به سیستم اضافه خواهند شد. بخش مهم این تیتر، روشی است که من نمونه ای از کلاس AppUserManager را به دست آورده ام و به کمک آن اطلاعات کاربران را مدیریت می کنم. با توجه به اینکه می خواهم توابع مدیریتی مختلفی را پیاده سازی کنم، از کلاس AppUserManager به صورت مکرر استفاده خواهم کرد. همچنین برای ساده سازی کد ، در Admin controller از مشخصه ی UserManager استفاده کرده ام. اسمبلی Microsoft.Owin.Host.SystemWeb متدهای گسترشی ای را به کلاس HttpContext اضافه می کند که یکی از این متدها GetOwinContext است. این کار باعث می شود که از طریق شیء IOwinContext ،شیء زمینه مبتنی بر هر درخواست (per-request context object) در OWIN API ایجاد شود.نتیجه استفاده از IOwinContext در نرم افزار مبتنی بر فریمورک MVC چندان جالب نمی شود، اما افزونه دیگری به نام GetUserManager< T > وجود دارد که کاربرد آن دریافت نمونه های کلاس user manager است.

نکته :

همانطور که احتمالا تا به الان متوجه شده اید، متدهای گسترشی بسیاری در هویت ASP.NET وجود دارند. در مجموع API را می توانید ترکیبی در نظر بگیرید که سعی می کند OWIN ، کارکرد هویت انتزاعی و پیاده سازی ذخیره سازی حافظه concrete Entity Framework را ترکیب کند.


برای مشخص کردن کلاس AppUserManager ای که قبل تر در این فصل ایجاد کردم، GetUserManager را همراه با پارامتر نوع ژنریک فراخوانی کرده ام، مانند زیر:

...
return HttpContext.GetOwinContext().GetUserManager< AppUserManager >();
...

پس از آنکه به نمونه ای از کلاس AppUserManager دست یافتم، می توانم کار پرس و جو جهت ذخیره سازی داده را آغاز کنم. مشخصه ی AppUserManager.Users برشمارشی از اشیاء کاربری را برگشت می دهد ( نمونه های کلاس AppUser در نرم افزار ام) که می توان آن ها با استفاده از LINQ دستکاری و پرس و جو کرد.
در متد indext action ، مقدار مشخصه ی Users را به متد View عبور داده ام به گونه ای که می توان جزئیات کاربران را در view لیست کرد. تیتر 10-13 محتوای داخل فایل Views/Admin/Index.cshtml را نشان می دهد. این فایل را با راست کلیک کردن بر روی متد Index action و انتخاب Add View از منوی باز شده ایجاد کرده ام.

@using Users.Models
@model IEnumerable< AppUser >
@{
    ViewBag.Title = "Index";
}
< div class="panel panel-primary" >
    < div class="panel-heading" > User Accounts
    < /div >
    < table class="table table-striped" >
        < tr >< th >ID< /th >< th >Name< /th >< th >Email< /th >< /tr >
        @if (Model.Count() == 0) {
        < tr >< td colspan="3" class="text-center" >No User Accounts< /td >< /tr >
        } else {
            foreach (AppUser user in Model) {
                < tr >
                    < td >@user.Id< /td >
                    < td >@user.UserName< /td >
                    < td >@user.Email< /td >
                < /tr >
            }
        }
    < /table >
< /div >
@Html.ActionLink("Create", "Create", null, new { @class = "btn btn-primary" })

این view شامل جدولی با ردیف هایی به ازای هر یک از کاربران و ستون هایی برای ID منحضر به فرد، نام کاربری و آدرس ایمیل است. اگر کاربری در دیتابیس وجود نداشته باشد، در این صورت مانند شکل 4-13 پیامی نمایش داده می شود.


آموزش احراز هویت در ASP.Net MVC 5

برای به سرانجام رساندن عمل Create در Admin controller لینکی را در View ایجاد کرده ام ( و با استفاده از Bootstrap آن را به شکل دکمه ای درآورده ام). تا اندکی دیگر جهت پشتیبانی از افزودن کاربران این عمل را پیاده سازی خواهم کرد.

ریست کردن دیتابیس

زمانی که نرم افزار را باز کنید و به آدرس /Admin/Index بروید، نمایش دادن محتواهای رندر شده در View اندکی زمان می برد. دلیل این اتفاق این است که Entity Framework به دیتابیس متصل شده و متوجه می شود که هیچ طرحی تعریف نشده است. ویژگی Code First از کلاس هایی استفاده می کند که برای ایجاد طرح (schema) و آماده کردن این طرح برای پرس و جو شدن و ذخیره سازی داده قبل تر در این فصل تعریف کردم ( برخی از این کلاس ها در اسمبلی های identity موجود هستند) .
پس از باز کردن پنجره ی Visual Studio SQL Server Object Explorer و توسعه دادن ورودی طرح دیتابیس IdentityDB می توانید نتیجه را مشاهده کنید. این نتیجه شامل جداول و اسامی ای مانند AspNetRoles و AspNetUsers هستند.
اگر می خواهید دیتابیس را پاک کنید تنها کافیست بر روی آیتم IdentityDbراست کلیک کنید و از منوی باز شده Delete را انتخاب کنید. هر دو گزینه نمایش داده مربوط به پاک کردن دیتابیس را تیک بزنید و برای پاک کردن دیتابیس بر روی دکمه OK کلیک کنید.
بر روی آیتم دیتابیس راست کلیک کنید و (مانند شکل 3-13 ) Add New Database را انتخاب کنید و در بخش مربوط به اسم دیتابیس ، IdentityDb را وارد کنید. برای ایجاد یک دیتابیس خالی بر روی OK کلیک کنید. دفعه بعد که نرم افزار را باز کنید و به آدرس Admin/Index بروید، Entity Framework خواهد فهمید که هیچ طرحی وجود نداشته و دیتابیس را مجددا ایجاد می کند.


ایجاد کاربران

در این بخش می خواهم به ازای هر یک از ورودی هایی که نرم افزار من دریافت می کند از اعتبارسنجی مدل فریمورک MVC (MVC framework model validation) استفاده کنم. ساده ترین راه برای انجام این کار ایجاد مدل های view ساده برای هر یک از عملیات هایی است که controller من از آن ها پشتیبانی می کند. برای تعریف کلاس نمایش داده شده در تیتر 11-13 فایل کلاسی به نام UserViewModels.cs را در فولدر Models اضافه کرده ام. همزمان با تعریف مدل های بیشتر برای پیاده سازی ویژگی های بیشتر، کلاس های دیگری را به این فایل اضافه خواهم کرد.
تیتر 11-13 محتوای داخل فایل UserViewModels.cs

using System.ComponentModel.DataAnnotations;
 namespace Users.Models {
public class CreateModel { [Required]
public string Name { get; set; } [Required]
public string Email { get; set; } [Required]
public string Password { get; set; }
}
}

اسم مدل اولیه ای که تعریف کرده ام CreateModel است. این مدل مشخصات پایه ای که برای ایجاد حساب کاربری، نام کاربری، آدرس ایمیل و رمز عبور که من به آن ها نیاز دارم را تعریف می کند. برای اینکه نشان دهم که مقادیر برای هر سه مشخصه تعریف شده در این مدل ضروری هستند، Required attribute را از System.ComponentModel. DataAnnotations namespace به کار گرفته ام.
دو متد از Create action را به admin controller اضافه کرده ام. این متدها تحت تاثیر لینک موجود در index view و مربوط به بخش قبل قرار داشته و برای درخواست GET ، view ای را در اختیار کاربر قرار می دهد و برای درخواست POST ، form data را پردازش می کند. می توانید متد های action جدید را ببینید.

using System.Web; using System.Web.Mvc;
using Microsoft.AspNet.Identity.Owin; using Users.Infrastructure;
using Users.Models;
using Microsoft.AspNet.Identity; using System.Threading.Tasks;
namespace Users.Controllers {
public class AdminController : Controller {
public ActionResult Index() { return View(UserManager.Users);
}
public ActionResult Create() { return View();
}
[HttpPost]
public async Task< ActionResult > Create(CreateModel model) { if (ModelState.IsValid) {
AppUser user = new AppUser {UserName = model.Name, Email = model.Email}; IdentityResult result = await UserManager.CreateAsync(user,
model.Password);
if (result.Succeeded) {
return RedirectToAction("Index");
} else {
AddErrorsFromResult(result);
}
}
return View(model);
}
private void AddErrorsFromResult(IdentityResult result) { foreach (string error in result.Errors) {
ModelState.AddModelError("", error);
}
}
private AppUserManager UserManager { get {
return HttpContext.GetOwinContext().GetUserManager< AppUserManager >();
}
}
}
}

بخش مهم این تیتر متد Create است. این متد آرگومان CreateModel را گرفته و زمانی که administrator داده ی فرمی خود را submit می کند، این آرگومان احضار می شود. برای آن که مطمئن شوم داده هایی که من دریافت می کنم شامل مقادیری است که به آن ها نیاز دارم، از مشخصه ی ModelState.IsValid استفاده می کنم. اگر داده های دریافتی من شامل تمامی مقادیری باشد که من به آن ها نیاز دارم، در این صورت نمونه ی جدیدی از کلاس AppUser را ایجاد می کنم و آن را به متد UserManager.CreateAsync می دهم. مانند زیر:

...
AppUser user = new AppUser {UserName = model.Name, Email = model.Email};
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
...

نتیجه ی حاصل از متد CreateAsync یک پیاده سازی از رابط IdentityResul است. به گونه ای که این پیاده سازی خروجی این عملیات را از طریق مشخصات لیست شده در جدول زیر توصیف می کند.

نام
توضیحات
Errors
بر شمارشی رشته ای را برگشت می دهد که در طی انجام عملیات خطاهای رخ داده را لیست می کند.
Succeeded
در صورتی که عملیات با موفقیت انجام شود true را برگشت می دهد.

استفاده از متدهای ناهمگام هویت ASP.NET

می دانید که تمام عملیات های دستکاری داده های کاربر مانند متد UserManager.CreateAsync که من در تیتر 12-13 استفاده کرده ام به صورت متدهای ناهمگام موجود هستند. چنین متدهایی را می توان به راحتی در کنار عبارت های کلیدی await و async به کار برد. استفاده از متدهای ناهمگام هویت این امکان را به action method های شما می دهد تا به صورت ناهمگام اجرا شوند و به دنبال آن خروجی کلی نرم افزارتان بهبود یابد.
هرچند می توانید از متدهای گسترشی همگام که توسط Identity API ارائه شده اند نیز استفاده کنید. تمامی متدهای ناهمگامی که به صورت معمول استفاده می شوند، دارای یک wrapper ناهمگام هستند. به گونه ای که بتوان کارکرد متد UserManager.CreateAsync را از طریق متد همگام UserManager.Create فراخوانی کرد. ترجیح شخصی من متدهای ناهمگام است و به شما هم توصیه می کنم از همین متدها در پروژه هایتان استفاده کنید. متدهای همگام بیشتر در ایجاد کدهای ساده تر و زمانی که بخواهید عملیات های متعدد وابسته ای را اجرا کنید کاربرد دارد. به همین دلیل برای باز کردن مطلب من از این متد در بخش "پیگردی دیتابیس" در فصل 14 استفاده کرده ام.
برای آن که مشخص کنم که آیا در ایجاد کاربران جدید در دیتابیس موفق بوده ام، مشخصه ی Succeeded را در اکشن متد Create ارزیابی می کنم. اگر مشخصه ی Succeeded برابر با true شود، در این صورت مرورگر را به سمت Indexaction هدایت می کنم به گونه ای که لیستی از کاربران نمایش داده شود.

...
if (result.Succeeded) {
return RedirectToAction("Index");
} else {
AddErrorsFromResult(result);
}
...

اگر نتیجه مشخصه ی Succeeded برابر با false شود، در این صورت من متد AddErrorsFromResult را فراخوانی می کنم. این متد پیام های حاصل از مشخصه ی Errors را برشمارش کرده و آن ها را به مجموعه ای از model state error ها اضافه می کند. با انجام این کار می توان از ویژگی تایید مدل فریمورک MVC بهره برد. همزمان با ساخت کارکرد و عاملیت administraton controller خود، باید خطاهای حاصل از عملیات های دیگر را پردازش کنم. آخرین مرحله ایجاد view ای است که این امکان را به administrator می دهد تا حساب های کاربری جدید را بسازد. محتوای داخل فایل e Views/Admin/Create.cshtml نشان داده شده است.

@model Users.Models.CreateModel
@{ ViewBag.Title = "Create User";}
< h2 >Create User< /h2 >
@Html.ValidationSummary(false)
@using (Html.BeginForm()) {
< div class="form-group" >
< label >Name< /label >
@Html.TextBoxFor(x = > x.Name, new { @class = "form-control"})
< /div >
< div class="form-group" >
< label >Email< /label >
@Html.TextBoxFor(x = > x.Email, new { @class = "form-control" })
< /div >

< div class="form-group" >
< label >Password< /label >
@Html.PasswordFor(x = > x.Password, new { @class = "form-control" })
< /div >
< button type="submit" class="btn btn-primary" >Create< /button >
@Html.ActionLink("Cancel", "Index", null, new { @class = "btn btn-default"})
}


هیچ مورد خاصی در این view وجود ندارد. این view به شکل ساده ای نوشته شده و مقادیری را در کنار یکدیگر قرار داده است که فریمورک MVC به مشخصات کلاس مدلی مقید خواهد شد که این مشخصات به اکشن متد Create داده می شود.


برای مطالعه سرفصل آموزش پیشرفته MVC کلیک نمایید .

1397/07/01 5011 887
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...