اختبار وشرح توابع Details و Delete

في هذه المقالة سوف نقوم بشرح توابع Details و Delete المولدة تلقائياً، حيث تختص هذه التوابع في إنشاء صفحة خاصة لعرض تفاصيل السجل من قاعدة البيانات، وحذف سجل من قاعدة بيانات عن طريق إنشاء صفحة لتأكيد قرار الحذف.

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

للبدأ قم بفتح المتحكم  Books وانتقل إلى التابع Details

  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);
        }


إن  محرك MVC قام بتوليد هذا التابع ونلاحظ وجود تعليق قبل التابع يعرض طلب HTTP الذي  يستدعي هذا التابع

وهذا الطلب هو GET حيث أن الرابط مؤلف من ثلاث أجزاء : المتحكم Books والتابع Details وقيمة البارمتر Id

إن تقنية Code First تجعل من السهل البحث عن البيانات باستخدام التابع Find

حيث أن هناك ميزة حماية مهمة في تابع Details وهي أنه يتم التحقق من أن التابع Find قد وجد الكتاب قبل تنفيذ أي شيء آخر في الكود

على سبيل المثال قد يقوم الهاكر بعمل أخطاء في الموقع من خلال تغيير الرابط من http://localhost:xxxx/Books/Details/1 إلى http://localhost:xxxx/Books/Details/12345

أو أي قيمة أخرى لا تمثل أي كتاب

فإذا لم نقم بعمل فحص لقيم null فإن ذلك سيؤدي إلى أخطاء في قاعدة البيانات

شرح توابع Delete و DeleteConfirmed

// GET: Books/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: Books/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Book book = db.Books.Find(id);
            db.Books.Remove(book);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

نلاحظ أن تابع HTTP Get Delete لايحذف الكتاب المحدد حيث أنه يعيد View تحتوي الكتاب حيث يمكن من خلالها استدعاء التابع HttpPost Delete  من أجل حذف الكتاب

إن تنفيذ عملية الحذف أو الإضافة أو التعديل في طلب Get يؤدي إلى تغرة أمنية

للمزيد من المعلومات في الرابط التالي  ASP.NET MVC Tip #46 — Don’t use Delete Links because they create Security Holes.

إن تابع HttpPost Delete يحذف الكتاب حيث أن هذا التابع له الأسم DeleteConfirmed

إن الشكل العام لتابعي الحذف هو كما يلي

// GET: Books/Delete/5 
public ActionResult Delete(int? id)

// POST: Books/Delete/5 
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken] 
public ActionResult DeleteConfirmed(int id)

لعمل تحميل زائد للتوابع فإن (common language runtime (CLR تفرض أن يكون للتوابع نفس الأسم ولكن مختلفة في البارمترات

ولكن هنا نحتاج لتابعي حذف (تابع GET  و تابع POST ) وكلاهما لهما نفس البارمترات(بارمتر واحد من النوع int)

وللتغلب على هذه المشكلة يوجد حلين

الأول: إعطاء التوابع أسماء مختلفة  وهذا ما قام به محرك MVC في المثال السابق ولكن هذا سيؤدي إلى مشكلة صغيرة

إن ASP.NET تقوم بتحويل أجزاء الرابط إلى التوابع من خلال الأسم وإذا قمنا بإعادة تسمية التابع فإن التوجيه سيكون غير قادر على إيجاد التابع والحل هو كمارأينا في المثال وهو إضافة الخاصية (“ActionName(“Delete إلى تابع DeleteConfirmed وهذا يؤدي إلى أن نظام التوجيه يقوم بالتحويل بشكل فعال حيث أن الرابط الذي يتضمن Delete/ 

من أجل طلب POST request سيستدعي التابع DeleteConfirmed

الحل الثاني: هو استخدام التوابع التي لها أسماء متماثلة حيث أن لائحة البارمترات تتغير من أجل تابع POST حيث يتم تضمين بارمتر غير مستخدم

على سبيل المثال بعض المطورين يضيفون بارمتر من النوع FormCollection الذي يمرر إلى تابع POST  حيث أن هذا البارمتر لايتم استخدامه في التابع

 public ActionResult Delete(FormCollection fcNotUsed,int id=0)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

 الآن قمنا بإكمال تطبيق  ASP.NET MVC الذي يخزن الكتب وأنواعها في قاعدة البيانات local DB

حيث أصبح بإمكاننا إضافة وحذف وتعديل  و البحث عن الكتب

تغذية راجعة

اتمنى عدم التردد في الاستفسار عن أي مفهوم تم ذكره في هذا التدوينة، وأرجو تجربة ماورد في التدوينة بشكل فعلي وعدم الاكتفاء بالقراءة لتحقيق أكبر فائدة ممكنة، وكالعادة سأكون سعيد إن شاركتموني تجربتكم وتصويباتكم في حال وجود أخطاء كتابية.

 

هذه المقالة مستندة إلى سلسلة دروس مايكروسوفت الرسمية للـ ASP.NET MVC، وذلك لترتيب الدروس المناسب واعتقادي بسلاستها وأهمية نقلها إلى العربية بأسلوب مناسب وتجربة تتوافق مع الأدوات المتاحة لنا والمتوفرة في منطقتنا.

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