نظرة سريعة على مميزات بيئة التطوير الجديدة فيجيوال ستوديو 2013 نسخة الويب

19-09-2013 ASP.NET | Visual Studio
إعلان
b1106fe1-7d72-46fd-a0f9-3b970336c0ac

قمت قبل أيام بتحميل نسخة الويب من بيئة التطوير Visual Studio 2013  لأطلع عليها وخصوصا أنه لم يمض وقت طويل على صدور النسخة Visua Studio 2012 ! إستنكرت بداية هذا التتابع السريع في النسخ التي تلحق بعضها بعضا من مايكروسوفت, فلم يمض الوقت الكافي لكي نستخدم بيئة التطوير VS2012 إلا وأصرت مايكروسوفت إصدار النسخة 2013! يبدو أن هناك بعض النقاط التي فاتها وضعها في النسخة السابقة.

أكثر ما يزعجني في مايكروسوفت هو سياستهم في إصدار البرمجيات, تذكرني بسياسة شركة نوكيا قديما في إصدار الهواتف, فبعد أن أشتري الهاتف الأكثر تطورا من نوكيا أجد في اليوم التالي صدور ما هو أحدث منه, أعتقد أن الأمر سيكون مريحا أكثر لأي مبرمج الحصول على نسخة متكاملة من بيئة التطوير لمدة 4 أعوام على الأقل, وبعد تعطشه الشديد لوجود تحديثات جديدة تأتي مايكروسوفت على صهوة جوادها لتضع بين يديه منتج حديث بدل سابقه, ربما لمايكروسوفت رأي اخر ليس ضمن حساباتي ولكن كانت تلك مجرد رغبة في أن يصبح الأمر كذلك. عموما كتبت هذا الموضوع لأضع بعض الصور والمميزات التي وجدتها في نسخة الويب من بيئة التطوير Visual Studio 2013.

في بداية الأمر أحب أن اثني على إضافة قالب Blue إلى قائمة القوالب وهو القالب المستخدم في VS2010 وقد تم تجاهله في نسخة VS2012 وها هو الان يعود لنا في النسخة 2013 منقوصا بعض الشيئ بسبب التغيير الذي طرأ على شكل الأيقونات تماشيا مع نظام Windows 8, ولكن يبقى شيئ جميل أن نجد هذا القالب ضمن القائمة.

options

من الجدير بالذكر أيضا أن VS2013 هو مجرد تنظيم وتحسين ودمج للتقنيات التي تعج بها بيئة التطوير Visual Studio ولأني قمت بتحميل نسخة الويب فقد لاحظت التنظيم على مستوى تطبيقات الويب حتى الان.

project

لم تعد الشاشة ممتلئة بالخيارات الان, تم إدراج كافة أنواع المشاريع تحت مسمى ASP.NET Web Application

newproject

هل أصبح من السهل حقا إختيار نوع المشروع في ASP.NET بهذا الأسلوب الجديد ؟ لا يحدث ذلك فرق ولكنه أفضل شكلا من السابق, يمكنك الأن تحديد مشروعك ضمن سلسلة خطوات بدل من إختياره مباشرة, كافة أنواع المشاريع أدرجت تحت مسمى ASP.NET Web Application سواء أكان Web Forms, MVC, API أو غيرها فعند قيامك بإنشاء مشروع ASP.NET جديد تظهر لك شاشة حوار تطلب منك تحديد نوع وخصائص المشروع الذي ترغب بإنشائه.

chooseprojecttype

أكثر ما لفت نظري في هذه الشاشة هو نظام المصادقة في تطبيقات الويب "Authentication" في مشاريع ASP.NET, فقد تم تنظيمه بأسلوب رائع, يمكنك أن تحدد ماهية المصادقة التي ترغب باستخدامها في مشروعك, معظم الأحيان أرغب في إستخدام Internet Project والذي يأتي مثقلا بملفات المصادقة "AccountController" جاهزة الإستخدام, أضطر بعد ذلك لحذفها نظرا لطبيعة المشروع, يمكنني الان أن أقوم باستثنائها مباشرة في مرحلة الإنشاء, قامت مايكروسوفت أيضا بإضافة نوع خاص بالمصادقة يتعلق بالمنظمات "لم أطلع عليه بشكل معمق حتى الان"

authentication

منذ إصدار MVC 4 والنظام المعتمد في المصادقة هو SimpleMembership بدلا من سابقه ASP.NET Membership Provider المقيت والغير مريح إطلاقا!. يمكنك الحصول على معلومات إضافية عن Authentication داخل ASP.NET وكيف تقوم بإستخدامه من خلال هذا الرابط.

تأتي MVC 5 بشكل تلقائي مع VS2013 وهي النسخة الأحدث حاليا وأنا متفائل بها لسبب بسيط وهو إعتمادها إطار العمل Bootstrap داخل التطبيقات, بالتأكيد هذا الأمر إيجابي بالنسبة لي فلن أضطر بعد ذلك لأقوم بتحميل ملفات إضافية وإرفاقها مع التطبيق يدويا, Bootstrap يعتبر الان من أكثر أطر العمل المتعلقة بالتصميم إنتشارا نظرا لسهولة وبساطة التعامل معه ودعمه لمفهوم Responsive Design بالإضافة أيضا إلى الشكل الجميل والأنيق الذي يضفيه على التطبيق.

runproject

لا أريد القول أن أسلوب Scaffold الجديد لفت نظري لأنه لم يفعل ذلك بل كنت على علم بوجوده مسبقا من خلال قراءة بعض المقالات التي تتحدث حول هذا الموضوع, في بداية الأمر كان من الصعب علي أن أتقبل فكرة وجود أداة تقوم بكتابة الكودات عني, حاولت تقبلها في عدة مشاريع بعد أن قمت بمراجعة ما تقوم بتوليده مرات عديدة وأنا مقتنع الان أنها تفعل ما أريده تحديدا ولكن لم أستطع التخلص من عادة إعادة إلقاء النظر مرة أخرى على ما قامت بكتابته!

scaffolding

عند قيامك بإنشاء جدول جديد في قاعدة البيانات فستقوم بالتأكيد ببناء صفحة تقوم بإضافة البيانات على هذا الجدول, وصفحة لحذف البيانات وأخرى لتعديل البيانات وهذه العمليات هي عمليات شبه روتينية على معظم الجداول, لذلك بدل من إنشاء هذه الصفحات يدويا وإضاعة الوقت عليها يمكنك إستخدام Scaffolding الموجودة داخل ASP.NET لكي تقوم بتوليد الأوامر والصفحات تلقائيا.

يمكننا القول الان أن Scaffold من الإضافات الأساسية بعد أن كانت إضافة مريحة توفر عليك الوقت والجهد في كتابة العديد من الكودات, في بداية الأمر كانت مقتصرة فقط على MVC, الان أصبح بإمكانك إستخدام Scaffold خلال أي مشروع ASP.NET بما في ذلك Web Forms, كما أصبح بإمكانك الان إستخدام Web Forms داخل MVC و كذلك الأمر مع API, يمكنك دمج أكثر من تقنية داخل مشروع واحد .... جيد !

scaffolding1

هناك بعض خصائص Scaffold الغير متوفرة حاليا داخل Web Forms وستقوم مايكروسوفت بإصدار تحديثات بخصوصها قريبا, لكي تقوم بإستخدام Scaffold داخل Web Forms قم بإضافة MVC Dependencies أولا.

كمطور تطبيقات ويب يتوجب عليه أن يحافظ على جودة التصميم أثناء البرمجة على كافة المتصفحات. يقدم VS2013 شيئا مفيدا في هذه الجزئية, فمن خلال Browser Link أصبح بإمكانك تشغيل مشروعك على أكثر من متصفح في نفس الوقت, قم بإختيار Browse With ثم قم بتضليل المتصفحات المتاحة.

browser-link

والجميل في الأمر أيضا هو إمكانية تحديث كافة المتصفحات من خلال زر واحد "Refresh", إذا قمت بإضافة تعديل بسيط على التصميم وترغب في رؤية النتائج مباشرة قم بتحديث المتصفحات من خلال Visual Studio بدل من الذهاب لكل متصفح بشكل منفرد.

a6d657b6-a042-4367-9e0b-8359c76537e1

أيضا تم تطوير محرر html داخل VS2013, يمكنك ملاحظة ذلك أثناء كتابتك كود html, ستظهر لك مجموعة من الخيارات الإضافية التي لم تكن موجودة في السابق.

فعلى سبيل المثال في VS2012 عند كتابتك لهذا الكود ستحصل على خيارات محدودة 

pdatatargetvs2012

وفي VS2013 أصبحت الخيارات أكثر تحديدا

pdatatargetvs2013

أعتدت في بناء التطبيقات على أن لا يحتوي أي ملف عدد كبير من السطور لكي لا يصبح الأمر معقدا في البحث عن شيئ ما, بل عادة ما أقسمها لمجموعة ملفات, لا أعتقد أني سأستمر في هذا الأمر بعد إضافة مايكروسوفت الجديدة على Scrolling Bar

scrolling

بالتأكيد هذا أفضل بكثير مما كان الأمر عليه سابقا, فبدل من الإستمرار في الصعود والنزول داخل الصفحة بإستخدام Scroll Bar لإيجاد شيئ ما ستظهر لك صورة مصغرة عن الكود في الملف وعند تمرير الماوس على جزء معين سيظهر لك الكود في ذلك الجزء أكثر وضوحا.

كما شاهدنا سابقا جاءت نسخة الويب من بيئة التطوير Visual Studio 2013 بمجموعة من الكماليات البعض يعتبرها غاية في الأهمية والبعض الاخر يفضل أن يبقى على ما تعود عليه وارتاح معه وفي النهاية تعود حرية الإختيار لك ولرغباتك فإذا كنت تملك الوقت للإطلاع عليها وإستخدامها فستساعدك, وإذا كنت مشغولا في التطوير ولا وقت لديك للأشياء الجديدة فلن يؤثر ذلك أيضا.

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

عن محمد جمال

مهندس حاسوب ومطور برمجيات, أعمل Freelancer في تطوير تطبيقات الويب من خلال ASP.NET منذ عام 2007 قمت بإنشاء عدة مشاريع في مجالات مختلفة (المتحكمات الدقيقة, الأنظمة المضمنة, الروبوت, برامج سطح المكتب, أنظمة قواعد البيانات) ومن هواياتي الخط العربي

subscribe

إعلان
إعلان

ما هو السبام ولماذا يستخدم وكيف يعمل مع مجموعة من الطرق للتخلص منه برمجيا

14-09-2013 ASP.NET | Programming
إعلان

عند الشروع في بناء مدونة أو موقع شخصي يسمح بتفاعل المستخدمين من خلال صندوق التعليقات أو غيره "لا يطلب أن يكون المستخدم عضوا" فإن أول ما عليك أن تخشاه هو السبام, يعتبر كابوس لأصحاب المواقع والمدونات, يقتحمها ويقوم بتعبئة النماذج بمعلومات وهمية وتقديمها على أنها من مستخدمين حقيقيين, أذكر مرة أني دخلت مدونتي وفوجئت بأكثر من 130 تعليق ينتظر الموافقه, للوهلة الأولى ظننت أن إعدادات SEO والروابط قد آتت أُكلها, وأن جوجل قد أعد لي خوارزمية بحث خاصة بمدونتي, شعرت بلذة التدوين, ولكن ذلك لم يدم طويلا, فما إن قمت بفتح التعليقات لأقوم بالموافقه عليها أتفاجئ أني لم أفهم أي كلمة منها, لم أعلم ما العلاقة التي تربط التعليق بمحتوى التدوينة ! أقول أني قد قمت بإنشاء نظام تدوين متكامل من خلال ASP.NET MVC 3  مع بعض snapshots للمشروع لأجد أن التعليق يخبرني أن خدمة Rss ليست فعالة على الموقع كما أني إستخدمت الطريقة التي أخبرتني عنها ولم تنجح, إنتظر قليلا ! ما الطريقة التي أخبرتك عنها ! ثم من أنت ! إسمك غريب جدا ولا يعتبر مألوف لي بالإضافة إلى أني لا أستطيع قراءته ! والعديد العديد على هذه الشاكلة.

advanced_blog_spam1

قمت بحذف كافة التعليقات بشكل يدوي وما هي إلا ساعات معدوده حتى أعيد نفس السيناريو ليحكي لي قصص وأساطير لم أسمع بها من قبل, كإجراء مبدئي قمت بإغلاق التعليقات في تلك الفترة على كافة المواضيع في المدونة وارتحت من عدم وجود التعليقات المزعجة لفترة لا بأس بها, ولكن ما فائدة المدونة بدون تعليقات ! أي شخص يدون يحب أن يرى اراء الناس وتعليقاتهم حول ما يكتب عنه, لا فائدة من وجود مدونة من دون تعليقات, فوجود التعليقات في التدوينة يحفز المدون على الإستمرار في الكتابة من دون كلل أو ملل لأنه وبالنتيجة يعرف أن هناك من يقرأ ما يكتبه ويتفاعل معه ويستفيد منه بل ويشاركه ارائه في الموضوع, بحثت عن Plugin لفلترة التعليقات ولم أجد سوى aksimet والذي بدورة بحاجة الى دفع مبلغ لا بأس به, بحثت عن بديل فوجدت Comment math plugin , أمر مزعج أن تضع للزائر صندوق يقوم بوضع حاصل جمع العدد 2 مع العدد 8 وفي بعض الأحيان يتطور الأمر لتقول له ضع 10 ! لم أحب هذا النوع من الإضافات حتى ولو كان الأمر على حساب الجهد المبذول في حذف التعليقات, قمت بعدها بإضافة delete pending comments plugin, كان الأمر جميلا, يمكنك حذف كافة التعليقات قيد الإنتظار "Pending" بزر واحد, أعجبني واستخدمته لفترة حتى اكتشفت أني أقوم بحذف تعليقات الزوار أيضا, قمت بعدها بإضافة Facebook Plugin لأتفادى هذه المشكلة والحمدلله كانت الإضافة ممتازة مع ملاحظتي لعدم وجود أشخاص كثر يفضلون إستخدامها وبعدها إنشغلت في بضعة مشاريع ولم أكن أملك الوقت الكافي لإدارة المدونة ولكتابة شيئ جديد !

حاليا وبعد بناء نظام التدوين الخاص بي "PAGER" لم يعد بالإمكان الإعتماد على الإضافات الموجودة في برامج إدارة المحتوى لذلك قررت أن أبحث في موضوع السبام, كيف يعمل وما الهدف منه وكيف يمكن التخلص منه, جمعت معلومات لا بأس بها وأود مشاركتها معكم.

SPAM البريد المزعج : أو البريد الغير مرغوب به, وهو إرسال كم كبير من البريد الإلكتروني إلى المتلقين دون الطلب منهم بهدف الترويج لفكرة أو سلعة أو معلومة معينة دون أي إعتبار لخصوصيات الاخرين, يتم هذا الأمر من خلال برامج تدعى robots تقوم بالتجوال في مواقع الإنترنت وفلترة عناوين البريد وحفظها ليتم وضعها في قوائم الإرسال الإعلانية.

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

لم يستخدم السبام 

يرجع هذا الأمر إلى عدة سنوات عندما قررت محركات البحث وعلى رأسهم شركة جوجل إستخدام مبدأ PageRank لتنظيم نتائج البحث "أولوية الصفحة بالظهور تعود إلى عدد المواقع التي تحتوي رابطا لتلك الصفحة", كان الأمر رائعا وبدأ يعود بنتائج بحث دقيقة ولكن هناك بعض الأشخاص بدأو باستخدام أسلوب google bombing.

فلنفرض أنك في إحدى صفحات موقعك الشخصي تتحدث عن سلعة معينه ولتكن "موبايل" وتريد أن تظهر صفحتك في النتائج الأولى للبحث عندما يقوم أحدهم بالبحث عن كلمة موبايل, تقوم بنشر رابط الصفحة على عدد كبير من المواقع وبالتالي سيزداد PageRank الخاص بصفحتك وستظهر في النتائج الأولى للبحث, وهذا ما يفعله السبامرز "Spammers".

طورت برامج السبام لتصبح أكثر ذكاء بحيث لا يمكن ملاحظتها, فسابقا كان من السهل تمييز السبام من غيره ففي موضوعك ولنفرض جزاف أنك تتحدث عن رحلة إلى القمر, وإذا بأحد التعليقات تتحدث عن "موسم تزاوج البط !", فعليا لا علاقة للموضوع بالتعليق وبالتالي سيكون من السهل تمييز إذا ما كانت هذه الرسالة سبام أم لا, ولكن حديثا أصبحت التعليقات قريبة من الموضوع وبعض الأحيان تطرح تعليقات مناسبة جدا لها علاقة وطيدة بالموضوع, في هذه الحالة من الصعب أن تميز ما إذا كان التعليق سبام أم لا, لا تدخل على الرابط المرفق بالتعليق, إذا كنت تشك من أن هذا التعليق سبام أم لا كل ما عليك القيام به هو تعديل التعليق وحذف الرابط ومن ثم الموافقة عليه, ستحظى بتعليق وستمنع السبامر من تحقيق هدفه.

كيف يعمل السبام 

السبام لم يعد مقتصرا فقط على البريد الإلكتروني بل أصبح يغزو المواقع ويقوم بتعبئة النماذج بشكل ألي وتقديمها ليصبح لديك مئات التعليقات الوهمية, الـسبامرز يعتمدون على برامج تدعى robots تقوم بالتجوال عبر الإنترنت بحثا عن نماذج Forms في الصفحات لتقوم بتعبئتها وتقديمها بشكل الي.

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

كيف تتخلص من السبام

stop_spam_sign

إنحسار التعليقات بالمستخدمين المسجلين في المدونة فقط هو أفضل الحلول في مواجهة السبام بإعتبار أن هذا المستخدم هو موثوق ولكن ليس عمليا, كصاحب مدونة لا يمكنني أن أطلب من الزائر التسجيل ليقوم بالتعليق فكل ما يريده هو إضافة تعليق ومن المنطقي أن لا يتطلب هذا الأمر خطوات معقدة  فطلب التسجيل في المدونة لإضافة تعليق من احد الاسباب التي تمنع تفاعل الاخرين مع مواضيعك, ولكن لا تقلق هناك بعض الحلول ستفي بالغرض ولا تتطلب أن يكون المستخدم عضو في الموقع.

registerforcomment

كابتشا - Captcha

recaptcha-example

وهي صورة تظهر للمستخدمين يمكنهم تمييز حروفها بسهوله ولكنها معقدة جدا بالنسبة لـ robotics software والحاسوب بشكل عام, تستخدم Captcha في تحديد إذا ما كان الشخص الذي يقوم بتعبئة النموذج Forms بشريا أم مجرد robot يقوم بتعبئة المعلومات بشكل آلي, تستخدم captcha في أسفل النماذج لتقوم بتعبئتها بالكلمة الموجوده في الصورة للتأكد أنك إنسان ولست robot.

سأقوم في وقت لاحق بوضع درس يتعلق حول إستخدام Captcha داخل تطبيقاتك من خلال ASP.NET

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

فرق الوقت بين تحميل الصفحة وتقديم النموذج

page-load-speed-2

المستخدم العادي سيقوم بالدخول إلى الصفحة وينتظرها لكي يتم تحميلها بالكامل ثم سيقوم بالنزول قليلا لقراءه المحتوى وبعدها يقرر ما إذا كان سيقوم بالتعليق أم لا, ثم إن تعبئة نموذج التعليقات يأخذ وقتا أيضا على عكس الروبوتس فهي تقوم بتحميل الصفحة وعمل تجزئه لها لمعرفة مكان النموذج ثم تقوم بتعبئته وتقديمه بشكل سريع جدا, من خلال هذه النقطة يمكننا أن نحدد ما إذا كان المعلق سبامر أم لا, ولكن كيف نقوم بها ؟

يمكننا فعل ذلك من خلال إنشاء Cookies بمجرد أن ينتهي المتصفح من تحميل الصفحة, نقوم بوضع الوقت الحالي بداخله, وعند قيام أي شخص بالتعليق وتقديم النموذج نقوم بطرح وقت إكتمال تحميل الصفحة من وقت تسليم النموذج "submit" فنحصل على قيمة معينه ولتكن 20 ثانية ! بالتأكيد لن يقوم بفعل ذلك أي شخص, لا يوجد من يقوم بقراءة الموضوع والتعليق عليه خلال 20 ثانية, هذا روبوت, ولكن لو حصلنا على فرق في الزمن بمقدار 5 دقائق يبدو هذا منطقيا أكثر لأن يقوم أي شخص بفعله, وبهذا الأسلوب تتمكن من معرفة الروبوتس من البشر.

إستخدام الكاش لمنع الطلبات المتكرره 

caching-architecture

في بعض الأحيان تقوم الروبوتس بملئ النموذج وتقديمة أكثر من مره خلال فترة زمنية قصيره, في المثال السابق كنا قد منعنا الروبوتس من القيام بتقديم أي نموذج قبل مده معينه, ولكن هنا سنسمح لها بتقديم طلب واحد فقط ضمن مده معينه وبعد ذلك نقوم بحفظ البيانات المتعلقة بالمستخدم مثل IP,Agent في الكاش لمدة زمنية معينة وفي حال وصول أي طلب جديد نقوم بإحضار البيانات مرة أخرى ومن ثم نقارنها بالقيم الموجوده داخل الكاش, إذا كانت موجوده فيجب عليه الإنتظار قليلا حتى تنتهي الفترة وبعدها يمكنه إعادة تقديم الطلب مرة أخرى, تماما مثل المنتديات فعند قيامك بالبحث عن شيئ داخل المنتدى وأردت المحاولة مجددا تجده يخبرك بأن عليك الإنتظار لمدة معينه قبل المحاولة من جديد, يمكنك إستخدام الكود التالي في حال كنت تستخدم ASP.NET MVC في بناء تطبيقك.

public class SpamFilter :ActionFilterAttribute
{
        public int Delay = 10; //time in seconds 
        public string ErrorMessage = "الرجاء الإنتظار قليلا";

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var request = filterContext.HttpContext.Request;
            var cache = filterContext.HttpContext.Cache;
            var info = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress;
            info += request.UserAgent;
            var target = request.RawUrl + request.QueryString;

            var hash = String.Join("", MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(info + target)).Select(x => x.ToString("x2")));
            if (cache[hash] != null)
            {
                filterContext.Controller.ViewData.ModelState.AddModelError("ExcessiveRequests", ErrorMessage);
            }
            else
            {
                
                cache.Add(hash, "", null, DateTime.Now.AddSeconds(Delay), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
            }
            base.OnActionExecuting(filterContext);
        }
}

ولكي تجبر أي Action بإتباع التعليمات السابقة نضيف إسم الفئه Class في الأعلى بنفس أسلوب Data Annotations

[HttpPost]
[SpamFilter(Delay=10)]
public ActionResult Index()
{
            if (ModelState.IsValid)
            {
                return Content("تم بنجاح");
            }
            else
            {
                return Content("نأسف, هناك فترة معينة عليك انتظارها");
            }
}

form1

وبعد تقديم النموذج مرتين بفارق زمني قصير كانت النتيجة كالتالي :

faild

قمت بإرفاق ملف يحتوي على FilterSpam Class وأيضا على المتحكم homeController وأيضا View خاصة بـ Index Action, يمكنك تحميلها وإرفاقها بمشروعك للقيام بتجربة عملية

إخفاء حقل من خلال CSS

css_logo

من المعروف أن الروبوتس تقوم بملئ كافة البيانات الموجوده داخل النموذج وتقديمها مباشرة, هي لا تميز بين الحقول المطلوب تعبئتها أو لا, بعضها متطور وربما يعلم أن هذا الحقل من نوع hidden لذلك لا يجب عليه تعبئته, ولكن ماذا لو قمنا بإضافة حقل عادي وقمنا بإخفاءه من خلال CSS ؟

الفكرة من هذه الطريقة هو قيامك بوضع حقل ومن ثم إخفاءه من خلال كودات CSS وعند تقديم الطلب إذا وجدت هذا الحقل يحتوي على قيمة فمن المؤكد أن الروبوت هي من قامت بذلك وبهذا تستطيع رفض الطلب بعد أن تبين أنه سبام, المستخدمون العاديون لن يلاحظو وجود هذا الحقل لأنه مخفي invisible لذلك لن يقومو بملئه وبهذا الأسلوب تستطيع التخفيف من المدخلات الوهمية.

يمكنك إستعمال هذه الخدعة لأخفاء حقل نصي معين داخل الفورم بدل من إستخدام النوع hidden field يمكنك إخفاءه من خلال CSS

invisible-css

بعد ذلك يمكنك تعين خاصية class للحقل المراد إخفاءه من خلال .

codehtml

يمكنك تحميل ملف الصفحة من هنا 

طرق أخرى

الطرق الموجوده في الأعلى هي طرق برمجية تستخدمها في حال كنت ترغب ببناء مكون التعليقات بيدك, ولكن هناك أيضا عدد من الحلول التي يمكنك الإعتماد عليها في إدارة التعليقات الخاصة بك على المدونة, يمكنك إضافة Facebook Comments Plugin إذا كنت ترغب من المعلقين إستخدام حساباتهم على Facebook في الزوار مع أن عدد لا بأس به من المعلقين لا يفضلون هذه الطريقة.

disqus

شخصيا إستخدمت إضافة من Disqus تقوم بالسماح للزوار بالتعليق بتوفير عدد من مواقع التواصل الإجتماعي لإستخدامها في التعليقات إضافة إلى Facebook, فهناك Google+ و Twitter و Disqus, وأيضا هناك خاصية التعليق كزائر إذا كنت لا ترغب بإستخدام أي من الخيارات المتاحة.

disqus-panel

توفر لك الإضافة لوحة تحكم لإدارة التعليقات على موقعك الإلكتروني من تعديل وحذف, والجميل أيضا أنها توفر لك أخذ نسخة إحتياطية من التعليقات, فلو أردت التخلي عنها وبناء نظام تعليقات خاص بك يمكنك أخذ نسخة من التعليقات وإضافتها على قاعدة البيانات الخاصة بك !

هل لديك طرق أخرى لتفادي السبام ؟ شاركنا بها !

ابحث حاليا عن خدمة مميزة في مجال النشرات البريدية تمكنني من إدارة قوائم البريد بدل من بناء واحدة جديدة من الصفر وحتى لو أضطر الأمر للدفع مقابل ذلك, في الحقيقة مقدمين النشرات البريدية أفضل في هذا المجال وذلك لأنهم يضمنون لك وصول رسائلك على صندوق الوراد inbox بدل من إعتبارها سبام أيضا :)

عن محمد جمال

مهندس حاسوب ومطور برمجيات, أعمل Freelancer في تطوير تطبيقات الويب من خلال ASP.NET منذ عام 2007 قمت بإنشاء عدة مشاريع في مجالات مختلفة (المتحكمات الدقيقة, الأنظمة المضمنة, الروبوت, برامج سطح المكتب, أنظمة قواعد البيانات) ومن هواياتي الخط العربي

subscribe

إعلان
إعلان

كيف تستخدم البرمجة في حل المشكلات التي تواجهك مع الملفات

01-09-2013 C-Sharp | Programming
إعلان

فكرت في إعادة كتابة إسمي مرة أخرى بخط مختلف فكلمة محمد جمال في الأعلى بهذا الخط لا تعجبني, قمت بالبحث عن مجموعة خطوط لعلها تسعفني في هذا الأمر, والحمدلله وجدت تشكيله كبيره من الخطوط بحجم 18.4 ميجابيت تحتوي على مجموعة خطوط عربية رائعة, وكالعادة جهزت نفسي لأقوم بفك ضغط الملف وتضليل كافة ملفات الخطوط ونسخها إلى مجلد الخطوط "Fonts" في النظام ولكن إعتقاداتي لم تكن دقيقة !

allfiles

المشكلة ! ظهرت لي مجموعة من المجلدات في ظاهرها منسقه جدا وتحمل بين طياتها العديد من العمل لأقوم به, كل مجلد من هذه المجلدات يتضمن مجلد فرعي, والمجلد الفرعي يتضمن مجلد فرعي اخر, وإذا حالفك الحظ فستجد ملف الخطوط مباشرة داخل هذا المجلد, وإذا لم يحالفك فستجد أيضا مجموعة من المجلدات الفرعية, كانت أشبه بمتاهه !

هل حقا يتوجب علي الدخول إلى كل مجلد لأقوم بنسخ محتوياته ! هل سأقوم بتبديد أكثر من 20 دقيقة في عمل روتيني ممل وأبقى طوال الوقت أتضرع إلى الله عل هذه المجلدات تنقص أو يتلاشى بعضها لكي أنهي هذا العمل بسرعة ؟ بالتأكيد لن أقوم بكل هذا العمل.

كالعادة فتحت علبة السجائر وأشعلت واحدة مع إرتشاف القهوة "الساده" وبعدها قمت باستدعاء صديقي الوفي Visual Studio وأنشأت مشروع جديد "Windows Forms Application"

wfa

وبعد أن أصبح المشروع جاهزا لأقوم بكتابة الكود قمت بإستدعاء IO namespace التي تحتوي على عدد كبير من الفئات "classes" ومنها ما هو مختص بالتعامل مع الملفات والمجلدات.

ionamespace

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

String MasterDirectory = "D:\\Fonts";
String dName = "D:\\NewFontFolder"; // Move fonts to this folder 
DirectoryInfo _info = new DirectoryInfo(dName); 
if (_info.Exists == false) // check if the directory exist or not 
      Directory.CreateDirectory(dName); //if not exist this will create it 

List<String> fontFile = Directory.GetFiles(MasterDirectory, "*tf*", SearchOption.AllDirectories).ToList();
            //set searchoption alldirectory to search in all subdirectories 

foreach (String file in fontFile) //loop to move all files 
{
      FileInfo currentfile = new FileInfo(file); //object to communicate with each file 
      //check if the file exist by name or not 
      if (new FileInfo(_info + "\\" + currentfile.Name).Exists == false) 
            currentfile.MoveTo(_info + "\\" + currentfile.Name);//if not exist, move
}

النتيجة

result

النتائج كانت مرضية جدا, قمت بتقليص أكثر من 20 دقيقة ممله إلى بضعة دقائق برمجية ممتعة, ولكن ما المهمه التي قامت بها الأسطر في الأعلى ؟ سأقوم بالتحدث عن البرنامج قليلا ليتسنى للبعض حل مثل هذه المشاكل بطريقة ممتعة.

أولا قمت بتحديد أسماء المجلدات التي أقوم بالعمل عليها ووضعها في متغيرات نصية "String" يسهل الوصول لها وتعديلها لاحقا, MasterDirectory هو مجلد الخطوط الرئيسي وسأطلق عليه "المجلد الرئيسي", أما dName فهو المجلد الذي ستجتمع فيه ملفات الخطوط بعد معالجتها وسأطلق عليه "المجلد الثانوي".

string MasterDirectory = "D:\\Fonts";
String dName = "D:\\NewFontFolder";

قمت بعدها بإنشاء كائن "object" من DirectoryInfo class للتعامل مع المجلدات وقمت بإعطائها إسم المجلد الثانوي dName لكي أقوم بإجراء العمليات عليه.

DirectoryInfo _info = new DirectoryInfo(dName);

الان نقوم بالتأكد إذا كان المجلد الثانوي موجود مسبقا أم لا, إذا لم يكن موجود نقوم بإنشائه, الداله Exists تقوم بإرجاع true إذا كان المجلد موجودا و false إذا لم يكن موجودا, الدالة CreateDirectory تقوم بإنشاء المجلد.

if (_info.Exists == false) // check if the directory exist or not 
       Directory.CreateDirectory(dName); //if not exist this will create it 

هذا السطر للبحث في كافة المجلدات والمجلدات الفرعية عن الملفات التي تنتهي بالحرفين tf وهي الملفات الخاصه بالخطوط وإمتدادها يكون إما ttf أو otf, القيم التي ترجع من تنفيذ الدالة GetFiles هي أسماء كافة الملفات التي تتطابق عليها شروط البحث على شكل List تتكون عناصرها من متغيرات نصيه, نقوم بتخزينها في object من نفس النوع "List" يحتوي على objects من نوع String.

الدالة GetFiles تحتاج إلى مجموعة من المعلومات Parameters 

Directory.GetFiles(DirectoryToSearch,searchPattern,searchOption);
  1. DirectoryToSearch : المجلد الذي ستجري بداخله عملية البحث عن الملفات.
  2. searchPattern : نمط الملفات التي ترغب بالبحث عنها
  3. searchOption : نستخدم searchOption.AllDirectories للبحث داخل كافة المجلدات الفرعية.
List<String> fontFile = Directory.GetFiles(MasterDirectory, "*tf*", SearchOption.AllDirectories).ToList();

لتتعرف أكثر على فئة List أنصحك بقراءه هذا الشرح.

الان وبعد أن حصلنا على List بأسماء الملفات "الخطوط" التي سنقوم بنقلها إلى المجلد الثانوي سنقوم بإجراء جملة دوران "foreach loop" على كافة عناصر List, ستمكننا جملة الدوران من معالجة ونقل كل عنصر بشكل منفرد.

من مميزات جملة الدوران "foreach" هي انك لا تحتاج إلى معرفة عدد العناصر في القائمة, كل ما عليك فعله هو إعطائها القائمة التي تريد تنفيذ جملة الدوران عليها ونوع العناصر في القائمة, وفي برنامجنا قمنا بتعريف عناصر القائمة من "String", يمكنك معرفة ذلك عن طريق السطر الذي قمنا من خلاله بتعريف القائمة <List<String.

بعد الحصول على List كاملة يمكننا الان عمل جملة دوران على كافة العناصر الموجوده بها لنأخذ قيمة كل عنصر ونضعها في المتغير file لتتم معالجته بشكل مستقل 

foreach (string file in fontFile)

عند أول دوران تقوم به جملة foreach ستكون قيمة المتغير file هي قيمة العنصر الأول من عناصر القائمة, وفي المرة الثانية تصبح قيمتها مساوية لقيمة العنصر الثاني وهكذا إلى أن تنتهي جميع العناصر.

نقوم الان بإنشاء كائن من الفئة FileInfo التي تمتلك مجموعة من الدوال "Functions" للتعامل مع الملفات, ما يهمنا في الوقت الحالي دالة "MoveTo" التي تقوم بنقل الملفات من مجلد إلى مجلد.

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

تماما كما فعلنا عندما حددنا المجلد المطلوب في الفئة DirectoryInfo نقوم بنفس العمل لتحديد الملف المطلوب 

FileInfo currentfile = new FileInfo(file); 

كما قلنا سابقا المتغير file يحتوي على أسم الملف الأول في المصفوفة, وبذلك نستطيع إجراء العمليات على الملف من خلال الكائن currentfile الذي يحتوي على مجموعة من الدوال منها "MoveTo", ولكن ماذا سيحدث إذا كان هناك ملف اخر في المجلد الثانوي بنفس الأسم ؟ 

عند تعريف كائن من فئه معينه "Object From Class", فإن الكائن يرث مجموعة من الصفات المحددة "Functions & Attributes", وفي مثالنا قمنا بتعريف الكائن currentfile من الفئه FileInfo أي أن معظم الدوال الموجودة في الفئة Fileinfo يمكن الوصول إليها من خلال الكائن currentfile, يمكنك معرفة المزيد عن Classes & Objects من خلال هذا الرابط.

مثل هذه الأمور محتمل حدوثها ولكي نجتنب المشاكل هنا نقوم بالتأكد قبل نقل الملف إذا كان هناك ملف اخر بنفس الإسم أم لا, نقوم بالتأكد من ذلك عن طريق الداله Exists.

if (new FileInfo(_info + "\\" + currentfile.Name).Exists == false)

الدالة Exists تقوم بإرجاع قيمة true  إذا كان الملف موجودا وقيمة false  إذا لم يكن موجودا ولكن في المثال السابق قمنا بمقارنة القيمة التي تقوم بإرجاعها الدالة Exists بقيمة false, وبالتالي ستنعكس قيمة التعبير, فإذا كان الملف موجودا فسيرجع التعبير قيمة false, وإذا لم يكن موجودا فسيرجع القيمة true.

 بعد أن قمنا بالتأكد من عدم وجود ملفات بنفس الأسم نقوم بنقل الملف إلى المجلد الثانوي

currentfile.MoveTo(_info + "\\" + currentfile.Name);

انتهى ! الان يمكنك التعديل عليه ليتناسب مع حاجتك, فأنت تعرف كيف تنشئ searchPattern لتحديد الملفات التي تبحث عنها, كما يمكنك تحديد مجلدات البحث searchOption, وتعرفت إلى جملة الدوران foreach, وتعرف جيدا كيف تستخدم الدالة MoveTo في نقل الملفات.

هذا البرنامج لإستخدامك الشخصي فقط ولا يستطيع أي شخص أن يقوم بإستخدامه, يمكنك إجراء بعض التطويرات على البرنامج ليكون سهل الإستخدام, قم بإضافة FolderBrowserDialog لتختار مجلد البحث, وقم بإضافة اخر لتحديد المكان الذي ترغب بنقل الملفات إليه, قم بوضع Combobox لتحدد خيارات البحث في المجلد "searchOption", وقم أيضا بوضع حقل من نوع Textbox لتحديد نمط البحث "searchPattern", ودعني أرى النتائج, سأكون سعيدا بها ! 

عن محمد جمال

مهندس حاسوب ومطور برمجيات, أعمل Freelancer في تطوير تطبيقات الويب من خلال ASP.NET منذ عام 2007 قمت بإنشاء عدة مشاريع في مجالات مختلفة (المتحكمات الدقيقة, الأنظمة المضمنة, الروبوت, برامج سطح المكتب, أنظمة قواعد البيانات) ومن هواياتي الخط العربي

subscribe

إعلان
إعلان

"أهلا بالعالم" ولا وجود لبرامج إدارة المحتوى بعد الان

28-08-2013 Blogging
إعلان

"أهلا بالعالم" هو عنوان التدوينة الإفتراضية التي تضاف تلقائيا بعد إكتمال تثبيت برنامج Wordpress , رحبت بي هذه العبارة مئات المرات على عكسي , فما إن أجدها حتى أقابلها بالحذف أو التعديل لأشعر بعدها أني قطعت شوطا طويلا في التطوير.

image02

قمت بإستخدام برنامج Wordpress في موقعي الشخصي لمدة عام كامل , وأيضا في بناء مواقع أخرى لبعض العملاء , كان رائعا جدا , لا أعتقد أن هناك نظام اخر يتقن البساطه كما هي موجوده في نظام Wordpress , توافقه التام مع محركات البحث أمر رائع ووجود الاف القوالب المجانية Themes والإضافات الجاهزة Plugins يوفر وقتا كبيرا في تطوير أي موقع ولكن .. !

في الحقيقة أردت خوض تجربة تدوين جديدة باستخدام تطبيق من برمجتي الخاصة , فإستخدام تطبيقاتك بشكل شخصي يمنحك فرصة أكبر لتجربة أدائها وتحسينها , إن العمل على نظام تدوين خاص بك قمت بتجهيزه ليتناسب مع إحتياجاتك تحديدا هو أمر ممتع جدا , كل أمر يقوم بتنفيذه أنت على معرفه كامله كيف تم تنفيذه وكيف يمكن تطويره , لن تفاجئك عباره new update available مجددا لأنك أنت من سيقرر وجودها.

لذلك وضعت لنفسي مجموعة من المبررات تحفزني على بناء نظام التدوين الخاص بي مثل : وجود العديد من الخيارات التي لا أقوم بإستغلالها في Wordpress ولن أستغلها نظرا لطبيعة موقعي "مدونه" أكتب فيها لا أكثر ولا أحتاج إلى أي شيئ سوى محرر نصوص أقوم بنسخ التدوينة بعد تنسيقها إليه , لا أحتاج إلى نظام التسجيل وإدارة المستخدمين لأنها بطبيعة الحال مدونة شخصية والشخص الوحيد المخول بالكتابه هو فقط أنا ! , التعليقات المزعجة Spam أصبح أمر لا مفر منه , هناك إضافات تجنبك هذا النوع من المشاكل لكني فضلت حينها أن أستخدم Facebok Comments Plugin , كما أن ترتيب المواضيع ضمن أقسام لا يعجبني في نظام التدوين , أحب أن أفعل دور الكلمات الدلالية Tags لا أن يدرج تحت تصنيف معين , واجهتني في الفترة الأخيرة أيضا مشاكل مع Theme كنت أستخدمه في المدونه وبسبب عدم توافقه مع تحديثات المدونه تعطلت معظم الروابط في لوحة التحكم وكان لا بد من تغييره مؤقتا عندما أرغب في إضافة موضوع جديد وبعد الإنتهاء أعود مره أخرى لأستعيد السابق , كما أن التحديثات المستمره أمر يزعجني.

لأعيش هذه التجربة قمت بإنشاء نظام تدوين بسيط خاص بي أستعمله في موقعي هنا لإدارة التدوينات التي أقوم بكتابتها وقمت بتسميته (Pager) لأنه وببساطه ... بسيط! , مجرد صفحات تعرض لك مواضيع أقوم بكتابتها وتتيح لك المجال للتجول بين الصفحات بشكل سلس (الأقدم , الأحدث) , هناك أرشيف لكافة المواضيع تعرض كل موضوع والتاريخ الذي أضيف به مع محرك بحث بسيط يعتمد بشكل كلي على محرك البحث جوجل , في الفترة الحالية تجاهلت العديد من الإضافات التي تعتبر إضافات أساسية في أي نظام تدوين.

ملاحظة : تطبيق Pager ما زال في المرحلة التجريبية ولم أصدره بشكل رسمي.

 أشياء لم أستخدمها :

  • التعليقات : حاليا لا أفكر في إضافة صندوق للتعليقات في المدونه نظرا لأنها ما زالت جديدة , كما أن إتاحة التعليقات للجميع يعرض البرنامج للعديد من المخاطر مثل Spam وبعض المشاكل الأخرى , إستخدام Captcha او Math Comment Spam هو أمر مزعج بالنسبة لي وللزائر , أفكر في إنشاء نظام تعليقات خاص يتجاوز مجموعة من المشاكل ولا يتطلب معلومات إضافية وذلك يحتاج إلى بعض الوقت , في إصدارات لاحقة من البرنامج سأقوم بإضافة هذه الميزه.
  • مواضيع ذات صلة : أعتبرها من الإضافات المهمه في أي برنامج تدوين , فهي تمكن الزائر من مشاهدة تدوينات أخرى لها علاقة بالتدوينة الحالية , هناك بعض الإشكاليات حول هذه الإضافة بخصوص سرعة الموقع إذ تستغرق بعض الوقت الإضافي للتنفيذ وخصوصا أن نظام Pager يعتمد على عرض كامل الموضوع ضمن الصفحة الرئيسية مما يعني أن المواضيع ذات الصلة ستظهر أيضا في الصفحة الرئيسية وهذا يتطلب عدد إضافي من الإستعلامات "Queries" -إستعلام لكل موضوع- , في الوقت الحالي لن يكون هناك عدد كبير من التدوينات , ولكن سأحرص على وضع الإضافة في الإصدارات الأخرى مع مراعات سرعة التطبيق.
  • الصفحات : في نظام Wordpress كنت أستخدم صفحتين , الأولى تتحدث عني والثانيه تعرض خدمات أقدمها , قمت بإلغاء الصفحة التي تتحدث عني واستبدلتها بصندوق بسيط يظهر أسفل كل تدوينه مع صورة شخصية ومجموعة روابط للشبكات الإجتماعية المشترك بها ورابط لموقع شخصي وفيه صفحة للخدمات التي أقدمها.
  • نظام التسجيل : بما أني الشخص الوحيد الذي يكتب في المدونه فلا حاجة لوجود نظام التسجيل , مستخدم واحد يفي بالغرض , أما بالنسبة للتعليقات فستكون متاحة للجميع بدون الحاجة لتسجيل دخول.
  • رفع الملفات : إذا كان Dropbox يمكنني من مشاركة ملفاتي مع الجميع , Flickr يسمح لي برفع الصور , Youtube يسمح لي برفع الفيديو وجميعها مجانا , فلم الحاجة لأقوم بعمل ملف إضافي وبرمجة Form لرفع الملفات , كما أن الخدمات المقدمه من هؤلاء تضمن للجميع بقاء الملفات مرفوعة طول الوقت , ولا أحتاج إلى مساحة إضافية من خطة الإستضافة الخاصة بي "تكلفة أقل" , هناك مجموعة من الاراء بخصوص رفع الملفات تجدها في سؤال طرحته بموقع Arabia I/O.
  • النشرة البريدية : ربما من الأجدر أن تحتوي كل مدونة شخصية لا تنشر مقالات بشكل يومي قائمة بريدية تستطيع من خلالها تنبيه المتابعين بوجود موضوع جديد.

في النهاية ما زالت قناعاتي أن ما يهم فعلا هو المحتوى لا برنامج إدارة المحتوى , فالعديد من الأشخاص قاموا بإستخدام Wordpress ولكن مدوناتهم للأسف فشلت ولم تكمل عامها الأول لا لضعف برنامج إدارة المحتوى بل لأنها لم تكن تهتم بالمحتوى أما البرامج فتقدم لك تسهيلات لإدارة وتنسيق المحتوى الخاص بك لا المحتوى نفسه.

عن محمد جمال

مهندس حاسوب ومطور برمجيات, أعمل Freelancer في تطوير تطبيقات الويب من خلال ASP.NET منذ عام 2007 قمت بإنشاء عدة مشاريع في مجالات مختلفة (المتحكمات الدقيقة, الأنظمة المضمنة, الروبوت, برامج سطح المكتب, أنظمة قواعد البيانات) ومن هواياتي الخط العربي

subscribe

إعلان
إعلان

تنويه : الأراء في هذا الموقع شخصية ولا تبت لأحد بصلة تحت أي حال من الأحوال