السلام عليكم ..
وجدت الكثيير من الإستفسارات عن طريقة عمل Uploader و سأشرح هنا مثال بأبسط الطرق الممكنة و سأشرح أكثر من طريقة في أوقات لاحقة و لكن هنا سنتناول موضوع رفع بيانات صورة و تخزينها في قاعدة البيانات على شكل Binary
بداية يلزمنا قاعدة بيانات و انا استخدم ال Sql Server و سيلزمنا أيضا جدول انا اسميته uploader به عدد من الحقول كالتالي :
id و هو المفتاح الوحيد
picName و هي تخزن اسم الصورة مع الإمتداد أيضا و من نوع varchar طبعا
picExt تخزن إمتداد الملف فقط و من نوع varchar و طبعا قد يسأل البعض و ماذا نستفيد من الإمتداد طالما هو ظاهر في الحقل السابق ؟ طبعا لأننا لو فكرنا في عمل معرض للصور مثلا قد نحتاج للبحث عن طريق الإمتداد و لتسهيل العملية خزناه في حقل لوحده.
pic من نوع Image و هي تخزن البيانات على شكل binary
الان نأتي لل HTML ..
أولا يلزمنا أن نضيف نوع ال Encryption الخاص بال form كالتالي :
<form id="Form1" method="post" enctype="multipart/form-data" runat="server">
نلاحظ أننا أضفنا enctype="multipart/form-data"
نحتاج ل HTMLControl و هي input control من نوع File ولكن كلنا نعلم ان ال HTMLControls لا تضاف لها الخاصية runat=server لذا سنضيفها يدويا لتصبح كالتالي :
<INPUT id="uploadFile" runat="server" type="file">
ثم نضيف زر من نوع WebControl لنفرض أن اسمه Button1 سوف نضغط عليه مرتين كي تفتح واجهة الكود عند الحدث Button1_Click
هنا سنحتاج لإضافة الأكواد التي ستقوم بالتالي :
1-إستقبال بيانات الصورة التي سنستخدمها من خلال الرافع.
2-أخذ معلومات أساسية مثل اسم الملف وإمتداد الصورة و حجمها.
3-تخزين الصورة في قاعدة البيانات.
أولا سأكتب الكود هنا :
private void Button1_Click(object sender, System.EventArgs e)
{
int slashPos,dotPos;
string fullPicName,picName,picExt;
int picLength;
// Read the posted uploaded image as binary bytes to save it in Database
fullPicName=this.uploadFile.PostedFile.FileName;
picLength=this.uploadFile.PostedFile.ContentLength;
byte[] picBuffer=new byte[picLength];
Stream picStream=this.uploadFile.PostedFile.InputStream;
picStream.Read(picBuffer,0,picLength);
// Get picture's record information (picture name,ext)
fullPicName=this.uploadFile.PostedFile.FileName;
slashPos=fullPicName.LastIndexOf(@"\");
dotPos=fullPicName.LastIndexOf(".");
picName=fullPicName.Substring(slashPos+1,fullPicName.Length-slashPos-1);
picExt=fullPicName.Substring(dotPos+1,fullPicName.Length-dotPos-1);
// save pic and its information in Databse
SqlConnection cn = new SqlConnection("Server=(local);Database=Northwind;Trusted_Connection=true;");
SqlCommand cmd = new SqlCommand("Insert Into uploader(picName,picExt,pic)Values(@name,@ext,@pic)",cn);
cmd.Parameters.Add("@name",picName);
cmd.Parameters.Add("@ext",picExt);
cmd.Parameters.Add("@pic",picBuffer);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
// Finishing :
Response.Write("تم تخزين الملف في قاعدة البيانات بنجاح.");
Response.End();
}نستطيع الوصول لبيانات الصورة التي نود تخزينها في قاعدة البيانات من خلال
uploadFile.PostedFile
حيث تحوي على خصائص و طرق مثل FileName و ContentLength و InputStream و غيرها ..
لننظر للكود التالي :
// Read the posted uploaded image as binary bytes to save it in Database fullPicName=this.uploadFile.PostedFile.FileName; picLength=this.uploadFile.PostedFile.ContentLength; byte[] picBuffer=new byte[picLength]; Stream picStream=this.uploadFile.PostedFile.InputStream; picStream.Read(picBuffer,0,picLength);
أخدنا اسم الملف كاملا مع المسار و خزناه في المتغير fullPicName ثم خزنا حجم الصورة بال byte داخل المتغير picLength و الذي يلزمنا من أجل حجز Buffer في الذاكرة يقابل حجم الصورة أو الملف و الذي أسميته هنا picBuffer ثم قمنا بإنشاء Binary Stream و هو عبارة عن مجموعة من ال Bytes التي تعبر عن بيانات ملف معين و حصلنا عليه من خلال الخاصية InputStream الخاصة بالملف الذي نود تخزينه.
طبعا قمنا بقراءة ال Stream و نقلة لل Buffer الخاص بالصورة المراد تخزينها .
ال Stream يحتاج إلى 3 باراميترز و هي كالتالي :
الأول وهو من نوع byte و يقوم بتخزين ما تم حفظه من ال Stream
التاني و هو نقطة قراءة بيانات الملف و طبعا سنبدأ من اول index و هو الصفر.
الثالث هو مكان نهاية القراءة و نحن نريد تخزين كل الصورة لذا سوف نضع متغير يعبر عن الحجم الكلي للصورة بال bytes و طبعا كان picLength
بعد ذلك ننتقل للمرحلة الثانية :
fullPicName=this.uploadFile.PostedFile.FileName;
slashPos=fullPicName.LastIndexOf(@"\");
dotPos=fullPicName.LastIndexOf(".");
picName=fullPicName.Substring(slashPos+1,fullPicName.Length-slashPos-1);
picExt=fullPicName.Substring(dotPos+1,fullPicName.Length-dotPos-1);طبعا هنا نستخدم طرق التعامل مع ال Strings و هي متوفرة في كل مكان بالنت و استخدمنا LastIndexOf لنحصل على ال Index الخاص بتواجد ال charachter داخل ال String طبعا يبحث عن أخر ظهور له ..
ملاحظة :
انا كتبت التالي :
(@"\")
انا أبحث عن \ ولكن بلغة ال #C او لغة السي و ما بعدها من نفس الأشباه تسبب له الإشارة \ مشكلة لذا يجب أن نكتبها \\ او نضع إشارة @ قبل النص.
أيضا استخدمنا SubString لنحصل على جزء فقط من النص الكلي .. طبعا نحتاج لتحديد نقطة بداية قص الجملة و طول الكلمة المقصوصة.
بالأخير أضفنا البيانات لقاعدة البيانات بشكل تقليدي و أظهرنا رسالة تفيد أن الصورة قد تم تخزينها و حجبنا ظهور الحقول مرة أخرى من خلال الطريقة Response.End
// save pic and its information in Databse
SqlConnection cn = new SqlConnection("Server=(local);Database=Northwind;Trusted_Connection=true;");
SqlCommand cmd = new SqlCommand("Insert Into uploader(picName,picExt,pic)Values(@name,@ext,@pic)",cn);
cmd.Parameters.Add("@name",picName);
cmd.Parameters.Add("@ext",picExt);
cmd.Parameters.Add("@pic",picBuffer);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
// Finishing :
Response.Write("تم تخزين الملف في قاعدة البيانات بنجاح.");
Response.End();أتمنى أن يكون الدرس مبسطا و مفهوما و كنت أرغب باستخدام ال SP ولكن حتى يتمكن الكل من فهم الدرس بعيدا عن مشاكل البعض مع ال Stored Procedures قررت تأجيلها لمرة أخرى :)
سأرفق الكود بالأسفل


