مقالات
2006/01/02 - i
ارسال MailMessage توسط SmtpMail.Send با امکان authentication
اول از همه ببخشید که خیلی عنوان مطلب عجیب قریب شد. بهتر از این به ذهنم نرسید.
ارسال ایمیل در ASP.NET پروسه بسیار ساده ای دارد که علاقه مندان همه می دانند و دوباره متذکر نمی شوم. اما اگر بخواهید که پارامترهای بیشتری را برای این عملکرد تنظیم کنید، راه حل چیست؟
به عنوان مثال اگر ارسال ایمیل مستلزم تعیین شناسه و رمز معتبر بروی شبکه باشد ، آنگاه دیگر کار به این راحتی نیست. مطمئنا اگر برنامه شما بروی شبکه ای با پیچیدگی کمتر ( مانند شبکه محلی ) قرار داشته باشد، با این محدودیتها برخورد نمی کنید ولی در شرایطی که Web Server که برنامه شما بروی آن نصب است با Mail Server که می خواهد ایمیل شمارا ارسال کند در یک Security Zone نباشد آنگاه نیاز به تنظیمات authentication برای ارسال ایمیل پیدا میکنید.
و اما راه حل: از آنجائی که ارسال ایمیل توسط SmtpMail.Send در ASP.NET از Microsoft CDO استفاده می کند، شما می توانید تمام پارامترهای مورد نیاز را در "Fields Property" یک MailMessage قرار دهید و سپس درخواست SmtpMail.Send را فراخوانی نمایید. فرض کنید که یک Object از نوع MailMessage با نام msg به ترتیب زیر ایجاد کرده ایم.
MailMessage msg = new MailMessage();
برای اینکه برنامه شما بتواند از روی Web Server درخواست ارسال ایمیل را در شبکه به Mail Server برساند باید sendusing رادر Fields مقدار دهی کنیم. برای مقدار دهی sendusing به ترتیب زیر عمل می کنیم
msg.Fields
 ["http://schemas.microsoft.com/cdo/configuration/sendusing"] = 2;
مقدار این خصوصیت از CdoSendUsing Enum گرفته می شود. که عدد 2 به معنی ارسال از طریق شبکه و با SMTP است.
اگر بخواهید Port را برای SMTP Server تعیین کنید
msg.Fields
["http://schemas.microsoft.com/cdo/configuration/
smtpserverport"
] = 25;
برای اینکه درخواست شما دارای authentication شود باید به ترتیب زیر عمل کنید.
msg.Fields
["http://schemas.microsoft.com/cdo/configuration/
smtpauthenticate"
] = 1;
مقدار این خصوصیت از CdoProtocolsAuthentication Enum گرفته می شود.
در آخر باید userid و password کاربر معتبری که مجوز ارسال ایمیل را دارد تعیین کنید.
msg.Fields
["http://schemas.microsoft.com/cdo/configuration/
sendusername"
] = userid;
msg.Fields
["http://schemas.microsoft.com/cdo/configuration/
sendpassword"
] = password;
که در آن userid و password با مقادیر دلخواه شما جایگزین شده اند.
حال با دو خط زیر و با مقدار دهی smtpServer با آدرس SMTP Server می توانید msg را که شامل تنظیمات ایمیل شما است ( از جمله موضوع و بدنه ایمیل) ارسال کنید.
SmtpMail.SmtpServer = smtpServer;
SmtpMail.Send(msg); 
یک مثال در این خصوص در لینک زیر است.

SMTP Authentication using System.Web.Mail (CDOSYS)

نوشته شده در ساعت 08:08 ايميل به دوستان نظر خوانندگان

2006/01/01 - i
کد کردن Connection String
اطلاعات Connection String در پروژه های Web Based از مهمترین مواردی است که برای مخفی ماندن آن از دید دیگران باید اهتمام ویژه ای به خرج داد. برای حفظ امنیت این اطلاع در ASP.NET راه کارهای مختلفی وجود دارد که در اینجا به یکی از آنها اشاره می کنم که کد کردن Connection String و سپس قرار دادن آن در web.config و یا متن برنامه است. . شاید این روش در نگاه اول روش بسیار امنی به نظر بیاید اما در واقع این طور نیست زیرا به راحتی Decode می شود ولی به هر حال مسکنی موقت است.
برای کد کردن یک رشته کاراکتری ابتدا لازم است System.Text را using کنید.
using System.Text;
سپس میتوانید به وسیله چند خط زیر یک رشته کاراکتری را که می تواند همان Connection String باشد کد کنید
string strConnectionString =
    "server=127.0.0.1;database=db;uid=user;pwd=pass";
string strToEncode = 
    Convert.ToBase64String 
    (ASCIIEncoding.ASCII.GetBytes(strConnectionString));
مقدار کد شده در متغییر strToEncode قرار گرفته است . این مقدار کد شده را در جائی مثل web.config قرار دهید. حال زمانی که در برنامه می خواهید Connection String را به یک SqlConnection بدهید تا آن را Open کند، باید آن را Decode کنید. برای این کار می توان تابع زیر را نوشت که مقدار کد شده را به عنوان پارامتر می گیرد و مقدار Decode شده را بر می گرداند
string Decoder(string strToEncode)
{
    return 
        ASCIIEncoding.ASCII.GetString
            (Convert.FromBase64String(strToEncode));
}
نوشته شده در ساعت 08:11 ايميل به دوستان نظر خوانندگان

2005/01/28 - i
پياده سازي ConnectionManager براي استفاده مناسب از Pooling
مقدمه

استفاده مناسب از Connection Pooling در برنامه يكي از مهمترين مباحث در زمينه برنامه نويسي وب مي باشد. عمده مديريت Connection Pool  را سرور  به عهده مي گيرد و شما نبايد به عنوان مثال نگران  تخصيص كانكشنهاي هاي بلا استفاده در Pooling  به درخواست جديد كانكشن در برنامه باشيد. اما يكسري نكات را براي كمك به اين مديريت بايد در نوشتن برنامه خود رعايت كنيد . براي دانستن آن نكات مطلب استفاده بهينه از Connection در دات نت را بخوانيد.اما اين كافي نيست . فرض كنيد كه برنامه شما داراي بلوك A و B باشد . در بلوك A درخواست بازكردن يك كانكشن وجود دارد و قبل از بستن آن كانكشن ، به بلوك B مي رود و در بدنه آن هم در خواست بازكردن يك كانكشن صادر مي شود در انتها بلوك B‌ كانكشن بسته و در انتهاي بلوك A هم كانكشن بسته شود . با فرض اين كه تمام اصول استفاده بهينه از Connection در دات نت هم رعايت شده باشد بازهم يك جاي كار ايراد دارد . آن هم درخواست دوبار باز شدن يك كانكشن كه اكنون باز است و دوبار بسته شدن همان كانكشن. حال اگر بحث Multi Threading را هم اضافه كنيد ،‌ابعاد مشكل پيچيده تر مي گردد.
 اما راه حل مناسبي وجود دارد ،‌آن هم داشتن يك كلاس به عنوان Connection Manager آن هم به صورت Singleton . در اين مقاله يك نمونه از اين كلاس را با زبان Visual Basic پياده سازي كردم كه حالت  Multi Threading  هم در نظر گرفته شده است.  توصيه مي كنم حتما در برنامه هايتان از آن و يا نمونه اي از اين الگو استفاده كنيد . بهتر است كه اين كلاس را به لايه DataAccess برنامه اضافه كنيد.

متن اين كلاس در فايل ConnectionManager.zip براي دانلود موجود است.

پياده سازي كلاس ConnectionManager

نام كلاس را ConnectionManager انتخاب كنيد و Constructor آنرا به حالت Private تبديل كنيد . اين به خاطر پياده سازي مدل Singleton است. متاسفانه در اين مقاله مجال پرداختن به بحث  Singleton Design Pattern نيست. تنها بايد اشاره كنم كه در طول زمان حيات  يك برنامه در زمان اجرا آن ،‌از كلاس Singleton تنها و تنها يك Instance بايد در حافظه باشد. در نظر گرفتن اين Pattern براي كلاس ما بسيار الزامي است.

Private Sub New()

End Sub

سپس دو خط زير را به ابتداي كلاس اضافه كنيد

Imports System.Threading

Imports System.Data.SqlClient

تعريف متغييرهاي لازم 

Private ConnectionCounter As Integer

Private ConnectionString As String

Private Shared CMS As Hashtable = New Hashtable

براي دادن مقدار اوليه به متغيير هاي تعريف شده در New كدهاي زير را مي نويسيم كه در آن به جاي DB و UID و PWD مقادير مناسب را جايگزين مي كنيد.

Private Sub New()

    ConnectionCounter = 0

    ConnectionString = _

          "server=Server;database=DB;uid=UID;pwd=PWD"

End Sub

متغيير CMS كه از نوع HashTable مي باشد براي نگهداري Instance از كلاس ConnectionManager به ازاء هر Thread مي باشد كه key آن هم CurrentThread مي باشد . حال روش دسترسي به  Instance از اين كلاس را كه به ازاء هر Thread تنها و نتها يك نسخه در حافظه است  پياده سازي مي كنيم. آنرا به صورت يك Shared Property به صورت زير مي نويسيم.

Public Shared ReadOnly Property Instance() As ConnectionManager

    Get

       If (Not CMS.Contains(Thread.CurrentThread)) Then

           CMS.Add(Thread.CurrentThread, New ConnectionManager)

       End If

       Return CType(CMS(Thread.CurrentThread), ConnectionManager)

    End Get

End Property

حال دو متد GetConnection و ReleaseConnection  براي گرفتن و آزاد كردن كانكشن از كلاس را پياده سازي مي كنيم .

Public Function GetConnection() As SqlConnection

    ConnectionCounter += 1

    If (ConnectionCounter = 1) Then

        Connection = New SqlConnection(ConnectionString)

        Connection.Open()

    End If

    Return Connection

End Function

 

Public Function ReleaseConnection() As SqlConnection

    ConnectionCounter -= 1

    If (ConnectionCounter = 0) Then

        Connection.Close()

        Connection = Nothing

    End If

End Function

كار تمام شد. حال اين كلاس را مي توانيد در برنامه خود اضافه نمائيد و با خيال راحت براي گرفتن يك كانكشن خط زير را بنويسيد

ConnectionManager.Instance.GetConnection()

و براي آزاد كردن كانكشن خط زير را بنويسيم.

ConnectionManager.Instance.ReleaseConnection()

نوشته شده در ساعت 13:43 ايميل به دوستان نظر خوانندگان

مقالات من
آخرين مطالب

نقل از مطالب اين سايت با ذكر منبع مجاز ميباشد

( Summery )