سؤال

عندما بدأت في تطوير تطبيقات الويب ، قمت بتخزين تفاصيل المصادقة للمستخدم في متغيرين جلسة

 Session["UserName"]="username";
 Session["Password"]="paswword-123";

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

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

هل كانت مفيدة؟

المحلول

في الأساس ، النهج الكلاسيكي لتخزين القيم مباشرة في Session["something"] لديه عيوب اثنين:

  • السلاسل السحرية: إذا كنت خطأ something, ، يتجمع الرمز الخاص بك بشكل جيد ولكنك تحصل على خطأ في وقت التشغيل أو ، والأسوأ من ذلك ، خطأ غير مرغوب فيه في التعليمات البرمجية الخاصة بك.
  • يصب: بعد القراءة Session["something"], ، تحتاج إلى إلقاءه على النوع الذي تحتاجه. (هذا هو المقصود "ليس آمنًا".)

باستخدام كائن قوي من النوع يتم تخزينه في الجلسة ألغيت المشكلة الثانية. حسنًا ، في الواقع ، لا يزال يحتاج كائنك المخصص إلى أن يتم إلقاؤه ، لكنه يلقي فقط بدلاً من اثنين (أو عشرة) ، مما يقلل من احتمال حدوث خطأ ما. مرة أخرى ، الممثل الخاطئ هو شيء يتم اكتشافه فقط في وقت التشغيل.

هناك طريقة أخرى تتمثل في تغليف الوصول إلى متغيرات الجلسة في خصائص ثابتة:

public class MySession {
    public static string UserName {
        get { return (string)HttpContext.Current.Session["UserName"]; }
        set { HttpContext.Current.Session["UserName"] = value; }
    }
}

بالطبع ، يمكن دمج كلا النهجين ، مما يتيح لك تجميع الخصائص المتعلقة بالتجميع (اسم المستخدم وكلمة المرور) في كائن مشترك.

نصائح أخرى

يمكن أن يكون وجود فئة مستخدم مع حقلين مفيدًا لأسباب عديدة ، كما هو الحال بالنسبة لسلامة النوع ، إذا قمت بكتابة جلسة ["pasword"] في مكان ما ستحصل على خطأ لن يكون من السهل العثور عليه ، فسيتعين عليك التحقق من كليهما أسماء المعلمات في كل مكان. أنت بحاجة إلى أن تكونوا صحيحة ، ومصدر كبير للأخطاء. بمجرد تخزين كائن المستخدم بدلاً من سلسلتين غير متصلتين ، ستتمكن من استخدام نوع رمز آمن مثل user.password بدلاً من محاولة الوصول إلى كلمة المرور عن طريق مفهرس السلسلة في الجلسة. أيضًا إذا حصل المستخدم على المزيد من الحقول ، وهو أمر شائع جدًا ، فستضيفها ببساطة إلى فئة المستخدم ، وليس البدء في إنشاء معلمات وأسماء جديدة وتخزينها في كومة الجلسة.

أما بالنسبة لترميز الأنواع ، أعتقد http://en.wikipedia.org/wiki/type_safety يجب أن يساعد ، أو أي نوع آخر من المقالات حول الموضوع وهو ما أعتقده.

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

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

Session["UserName"] = "Freddy";
string theUserName = (string)Session["UserName"];

ومع ذلك ، يمكنك محاولة القيام بما يلي ، مما سيؤدي إلى أخطاء.

Session["UserName"] new StrangeDataClass(); //Uh Oh, that's not a string.
string theUserName = (string)Session["UserName"]; //unexpected behaviour based on StrangeDataClass.ToString() implementation.

للتغلب على هذا ، يجب عليك القيام بما يلي:

string theUserName = Session["UserName"] as string;
if (string != null)
    //The cast worked...
else
    //The cast failed, (or the string stored in session was null)

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top