الوصول إلى البيانات عن طريق المتحكم Controller

في هذه التدوينة سوف نقوم بإضافة BooksControlles class من أجل جلب و عرض بيانات الكتب في المتصفح باستخدام View Template.

قم بعمل Build للمشروع قبل الانتقال للخطوات التالية.

هذه المقالة جزء من سلسلة لتعلم أساسيات ASP.NET MVC للمبتدئين:

سنقوم اولاً بإضافة 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 بإضافة الملفات  والمجلدات  التالية:

  1.  ملف TypesController.cs في مجلد Controllers
  2. مجلد Views\Types
  3. ملفات 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، وذلك لترتيب الدروس المناسب واعتقادي بسلاستها وأهمية نقلها إلى العربية بأسلوب مناسب وتجربة تتوافق مع الأدوات المتاحة لنا والمتوفرة في منطقتنا.

مدير تقني وشريك مؤسس لـ فسيلة تِك، مبرمج متعدد المهارات، مهتم في إنجاز أمور استثنائية في مجال التكنولوجيا وأعمل جاهداً لترك أثر إيجابي في الحياة