في هذه التدوينة سوف نقوم بإضافة BooksControlles class من أجل جلب و عرض بيانات الكتب في المتصفح باستخدام View Template.
قم بعمل Build للمشروع قبل الانتقال للخطوات التالية.
هذه المقالة جزء من سلسلة لتعلم أساسيات ASP.NET MVC للمبتدئين:
- المقالة الأولى: أول موقع ويب لك باستخدام ASP.NET MVC
- المقالة الثانية: إضافة متحكمات Controllers لموقع ASP.NET MVC
- المقالة الثالثة: إضافة واجهة View لموقع ASP.NET MVC
- المقالة الرابعة: إضافة Model لموقع ASP.NET MVC
- المقالة الخامسة: إضافة Connection String والعمل مع قواعد البيانات LocalDB
- المقالة السادسة: الوصول إلى البيانات عن طريق المتحكم Controller
- المقالة السابعة: شرح وتجريب تابع التعديل Edit Method
- المقالة الثامنة: إضافة ميزة البحث إلى موقع ASP.NET MVC
- المقالة التاسعة: إضافة حقل جديد لقاعدة البيانات انطلاقاً من كود سي شارب Code First Method
- المقالة العاشرة: إضافة التحقق Validation إلى MVC Model وتطبيق مبدأ DRY
- المقالة الحادية عشر: اختبار وشرح توابع Details و Delete
سنقوم اولاً بإضافة TypesControlles class من أجل التعامل مع أنواع الكتب من إضافة وحذف وتعديل، في Solution Explorer قم بالنقر بزر الفأرة اليميني على مجلد Controllers ثم Add ثم Controller
في نافذة Add Scaffold قم باختيار MVC 5 Controller with views, using Entity Framework
ثم انقر Add
قم بعد ذلك بادخال اسم المتحكم TypesController، ومن أجل الحقل Model class قم باختيار (Type(ArabicArchive.Models، وفي الحقل Data context class قم باختيار (BookDBContext (ArabicArchive.Models. الصورة التالية توضح ماسبق:
بعد ذلك قم بالنقر على الزر Add.
سيقوم بعدها Visual Studio بإضافة الملفات والمجلدات التالية:
- ملف TypesController.cs في مجلد Controllers
- مجلد Views\Types
- ملفات Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml و Index.cshtml في مجلد Views\Types
إن Visual Studio يقوم بشكل اوتوماتيكي بإضافة CRUD action methods مع ال views المرتبطة بها وهذه العملية تعرف باسم scaffolding.
قم بتشغيل التطبيق وقم بالذهاب الى Types Controller من خلال إضافة Types/ الى الرابط الموجود في شريط العنوان للمتصفح. وبما أن التطبيق يعتمد على التوجيه الافتراضي المعرف في ملف App_Start\RouteConfig.cs فإن طلب المتصفح http://localhost:xxxxx/Types يوجه الى Index
action method للمتحكم Types.
بمعنى آخر أن طلب المتصفح http://localhost:xxxxx/Types هو نفس طلب المتصفح http://localhost:xxxxx/Types/Index
نتيجة التنفيذ هي عبارة عن لائحة (List) فارغة لأننا لم نقم بإضافة أي نوع.
قم بالنقر على رابط Create New لإضافة نوع جديد قم بعد ذلك بإدخال معلومات النوع ثم اضغط على زر Create.
ادخل معلومات النوع الأول كما هو موضح ثم اضغط على زر Create.
بالنقر على زر Create سيتم نقل البيانات التي قمنا بإدخالها في الحقول إلى المخدم ليتم تخزينها في قاعدة البيانات وبعدها يتم إعادة التوجيه إلى الرابط Types/ لنرى كل الأنواع المخزنة في قاعدة البيانات على شكل لائحة (List).
قم بإضافة أنواع اخرى بنفس الطريقة السابقة.
بعد أن قمنا بإضافة Types Controller سننتقل لإضافة Books Controller التعامل مع الكتب من إضافة وحذف وتعديل.
في Solution Explorer قم بالنقر بزر الفأرة اليميني على مجلد Controllers ثم Add ثم Controller
في نافذة Add Scaffold قم باختيار MVC 5 Controller with views, using Entity Framework
ثم انقر Add
قم بعد ذلك بادخال اسم المتحكم BooksController، ومن أجل الحقل Model class قم باختيار (Book(ArabicArchive.Models، وفي الحقل Data context class قم باختيار (BookDBContext (ArabicArchive.Models
الصورة التالية توضح ماسبق:
قم بتشغيل التطبيق وقم بالذهاب الى BooksController من خلال اضافة Books/ إلى الرابط الموجود في شريط العنوان للمتصفح
نتيجة التنفيذ هي عبارة عن لائحة (List) فارغة لأننا لم نقم بإضافة أي كتاب.
قم بالنقر على رابط Create New لإضافة كتاب جديد نلاحظ أنه هناك حقل TypeId هو عبارة عن قائمة منسدلة تحتوي على جميع أنواع الكتب التي قمنا بإضافتها حيث أننا نقوم عن طريق هذه اللائحة باختيار النوع و يتم أخذ قيمة الخاصية TypeId للعنصر الذي تم اختياره من اللائحة ليكون TypeId للكتاب الذي نقوم بإضافته.
سنقوم بتغيير اسم الحقل من TypeId إلى Type دون تغيير اي شيء في طريقة العمل الموضحة سابقا لاختيار النوع للكتاب، قم بالذهاب إلى الملف Views\Books\Create.cshtml وقم بإيجاد الـ TypeId label كما في الصورة التالية:
قم بتغيير النص الذي يظهر في ال label من “TypeId” ليصبح “Type” كما هو موضح بالصورة التالية:
سنبدأ الآن بإضافة بعض الكتب الى قاعدة البيانات:
قم بتشغيل التطبيق وقم بالذهاب الى BooksController من خلال اضافة Books/ الى الرابط الموجود في شريط العنوان للمتصفح، قم بالنقر على رابط Create New لإضافة كتاب جديد بعد ذلك قم بإدخال تفاصيل الكتاب مع تحديد النوع للكتاب.
بالنقر على زر Create سيتم نقل البيانات التي قمنا بإدخالها في الحقول إلى المخدم (السيرفر) ليتم تخزينها في قاعدة البيانات وبعدها يتم إعادة التوجيه إلى الرابط Books/ لنرى كل الكتب المخزنة في قاعدة البيانات على شكل لائحة (List)
قم بإضافة كتب اخرى بنفس الطريقة السابقة.
سننتقل الآن لشرح الكود المولد، قم بفتح الملف Controllers\BooksController.cs قم بالذهاب الى التابع Index
الكود التالي هو لجزء من Book Controller مع التابع Index:
public class BooksController : Controller { private BookDBContext db = new BookDBContext(); // GET: Books public ActionResult Index() { var books = db.Books.Include(b => b.Type); return View(books.ToList()); }
إن الطلب الذي يأتي للمتحكم Books سيعيد جميع السجلات في جدول Books ومن ثم سيتم تمرير النتائج الى Index view
السطر التالي من BooksController class يقوم بإنشاء object من BookDBContext ويمكن استخدام BookDBContext للاستعلام و تعديل وحذف الكتب:
private BookDBContext db = new BookDBContext();
رأينا في المقالات السابقة أن المتحكم يمكن أن يمرر بيانات أو objects الى view باستخدام ViewBag object.
ViewBag هو عبارة عن dynamic object يمكننا من تمرير المعلومات الى view، إن MVC تمنح إمكانية تمرير strongly typed objects إلى الـ view.
إن آلية scaffolding في Visual Studio تستخدم هذه الطريقة مع BooksController Class و TypesController Class وال views المرتبطة بهم عند توليد ال views و ال methods.
في الملف Controllers\BooksController.cs قم بالذهاب الى تابع Details، الكود التالي هو لتابع Details:
// GET: Books/Details/5 public ActionResult Details(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Book book = db.Books.Find(id); if (book == null) { return HttpNotFound(); } return View(book); }
إن البارامتر Id يمرر على أنه route data
على سبيل المثال http://localhost:17446/books/details/1
في هذا المثال يتم تمرير القيمة 1 للبارمتر Id ل details action في المتحكم books نستطيع أيضا تمرير البارمتر Id عن طريق query string كما يلي http://localhost:17446/Books/details?Id=1
في حال تم إيجاد الكتاب فإن instance من Book Model تمرر إلى Details view:
return View(book);
قم باستعراض محتويات ملف Views\Books\Details.cshtml ، ستلاحظ وجود التعليمة التالية في بداية الملف:
@model ArabicArchive.Models.Book
عن طريق وضع تعليمة model@ في بداية ملف ال view نستطيع تحديد نوع الobject الذي تقبله الـ view.
عند إضافة Book controller فإن Visual Studio وبشكل اوتوماتيكي قام بوضع تعليمة model@ في بداية ملف
Details.cshtml
إن تعليمة model@ تسمح لنا بالوصول الى Book object الذي قام المتحكم بتمريره الى view باستخدام Model Object. على سبيل المثال Details.cshtml template نلاحظ أنه في الكود يتم تمرير كل خاصية الى DisplayNameFor، و DisplayFor وهي عبارة عن توابع HTML Helpers.
وبنفس الطريقة فإن توابع Create و Edit و view template تمرر book model object.
قم باستعراض الملف Index.cshtml والتابع Index في ملف BooksController.cs، نلاحظ أنه في الكود يتم إضافة List object عندما يتم استدعاء View helper method في تابع Index:
// GET: Books
public ActionResult Index()
{
var books = db.Books.Include(b => b.Type);
return View(books.ToList());
}
عند إضافة Book controller فإن Visual Studio وبشكل اوتوماتيكي قام بوضع تعليمة model@ في بداية ملف
Index.cshtml
@model IEnumerable<ArabicArchive.Models.Book>
إن تعليمة model@ تسمح لنا بالوصول الى لائحة الكتب التي قام المتحكم بتمريرها الى ال view باستخدام ال Model object
على سبيل المثال في الملف Index.cshtml يتم المرور على كل الكتب باستخدام تعليمة foreach على Model object
@foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Type.Title) </td> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @Html.DisplayFor(modelItem => item.Description) </td> <td> @Html.DisplayFor(modelItem => item.PublishDate) </td> <td> @Html.DisplayFor(modelItem => item.Author) </td> <td> @Html.DisplayFor(modelItem => item.NumberOfPages) </td> <td> @Html.DisplayFor(modelItem => item.GoodreadsRate) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.Id }) | @Html.ActionLink("Details", "Details", new { id=item.Id }) | @Html.ActionLink("Delete", "Delete", new { id=item.Id }) </td> </tr> }
وبما أن Model object هو عبارة عن لائحة فإن كل عنصر في هذه اللائحة هو عبارة عن Book object، ويتم الوصول الى خصائص كل object كأي object نتعامل معه:
العمل مع SQL Server LocalDB
في Entity Framework Code First قمنا بتحديد قاعدة البيانات Books في connection string ولكن هذه القاعدة لم تكن موجودة بعد. لذلك فإن Code First قامت بإضافة قاعدة البيانات بشكل أتوماتيكي
يمكن التحقق من أن قاعدة البيانات قد تم إضافتها من خلال المجلد App_Data.
إذا لم نستطع رؤية ملف Books.mdf قم بالنقر على زر Show All Files في شريط أدوات Solution Explorer
قم بالنقر على زر Refresh ثم استعرض محتويات المجلد App_Data:
قم بالنقر مرتين على ملف Books.mdf لفتح SERVER EXPLORER. قم باستعراض مجلد Tables لرؤية جدول Books.
لاحظ أيقونة المفتاح بجانب Id وبشكل افتراضي فإن Entity Framework ستجعل الخاصية ذات الاسم Id هي المفتاح الأساسي Primary Key، للمزيد من المعلومات عن EF و MVC قم بالدخول للرابط التالي MVC and EF
قم بالنقر بزر الفأرة اليميني على الجدول Books وقم باختيار Show Table Data لرؤية البيانات التي تم إضافتها:
قم بالنقر بزر الفأرة اليميني على الجدول Books وقم باختيار Open Table Definition لرؤية بنية الجدول التي تم اضافتها من قبل Entity Framework Code First
لاحظ بنية الجدول Books حيث أن هذه البنية تقابل Book class الذي قمنا بإضافته سابقا.
إن Entity Framework Code First وبشكل أتوماتيكي تضيف هذه البنية لنا بالاعتماد على Book class
عند الانتهاء من العمل مع قاعدة البيانات قم بإغلاق الاتصال بالنقر بزر الفأرة اليميني على BookDBContext وقم باختيار Close Connection.
اذا لم نقم بإغلاق الاتصال ربما نواجه خطأ في المرة القادمة التي نقوم بها بتشغيل المشروع.
الآن اصبح لدينا قاعدة بيانات و صفحات لعرض و تحديث وتحرير البيانات في الدرس القادم سنكمل شرح الكود وسنضيف تابع SearchIndex و SearchIndex view من أجل البحث عن الكتب في قاعدة البيانات.
تغذية راجعة
اتمنى عدم التردد في الاستفسار عن أي مفهوم تم ذكره في هذا التدوينة، وأرجو تجربة ماورد في التدوينة بشكل فعلي وعدم الاكتفاء بالقراءة لتحقيق أكبر فائدة ممكنة، وكالعادة سأكون سعيد إن شاركتموني تجربتكم وتصويباتكم في حال وجود أخطاء كتابية.
هذه المقالة مستندة إلى سلسلة دروس مايكروسوفت الرسمية للـ ASP.NET MVC، وذلك لترتيب الدروس المناسب واعتقادي بسلاستها وأهمية نقلها إلى العربية بأسلوب مناسب وتجربة تتوافق مع الأدوات المتاحة لنا والمتوفرة في منطقتنا.