نوشته شده توسط
ssttss68
ممنون از راهنمای تون ولی این کد برای من کارساز نبود .
من پروژه رو با sql و سی شارپ نوشتم و ضمیمیه کردم که در صورت امکان بررسی بشه و ایراد کار مشخص بشه .
درخواستم اینه که درصورتی تو فرم مشتری ،نام مشتری و تو فرم کالا ،نام کالا و برند تکراری بود موقع ثبت خطا بده .
ممنون میشم اساتید راهنمایی کنن .
چند تا مورد رو در نظر بگیرید :
مورد اول اینکه کد کلاس FormLogin رو ببینید، در کد btsabt_Click برای SqlConnection مقدار Connection String رو صریحا مشخص کرده اید که ارتباطی با تنظیمات پروژه نداره و مستقل ئه.
اینکار رو نکنید، Connection String رو همیشه از یک منبع مشخص بخونید که بدون نیاز به ویرایش بخش های مختلف کد برنامه بشه تغییرش داد.
در جاهای مختلف مقدارش رو صریحا ننویسید، تغییرش نیازی به ویرایش کد نداشته باشه.
مخصوصا که در Properties.Settings.Default.DB1ConnectionString مقدارش رو دارید (منوی Project > test 3 Properties... > Settings)
و نیازی نیست که بخواهید مجددا مقدارش رو وارد کنید.
var con = new SqlConnection( Properties.Settings.Default. DB1ConnectionString);
test 3.exe رو در پوشه pro 99-11-13-v0\test 3\bin\Debug پیدا کنید، کنارش یک فایل متنی test 3.exe.config هست، اونجا ذخیره میشه.
private void btsabt_Click(object sender, EventArgs e)
{
var con = new SqlConnection( Properties.Settings.Default. DB1ConnectionString);
var com = new SqlCommand();
int i = 0;
مورد دوم اینکه هیچوقت مقدار ورودی کاربر رو مستقیما وارد کد SQL نکنید، چون برنامه تون نسبت به SQL Injection آسیب پذیر میشه.
کوئری شما این بوده :
"SELECT COUNT(*) FROM tb_login WHERE UserName='" + username.Text + "' AND Password='" + Password.Text + "'"
اگر کاربر به عنوان نام کاربری بنویسه x و بجای رمز عبور بنویسه y' OR 'a'='a شما همچین کوئری ای می سازید :
SELECT COUNT(*) FROM tb_login WHERE UserName='x' AND Password='y' OR 'a'='a'
و همیشه این WHERE برقراره و کاربر بدون نیاز به دانستن رمز عبور میتونه وارد بشه.
Preview.png
برای اینکه جلوی SQL Injection ها رو بگیرید می توانید از Parameters استفاده کنید :
com = new SqlCommand("SELECT COUNT(*) FROM tb_login WHERE UserName=@UserName AND Password=@Password", con);
com.Parameters.Add( new SqlParameter( "UserName", username.Text));
com.Parameters.Add( new SqlParameter( "Password", Password.Text));
مورد بعدی اینکه شما ()i = (int)com.ExecuteScalar رو داخل شرط if (con.State == ConnectionState.Closed) قرار داده اید، نباید ربطی به بسته بودن con داشته باشه، بیرون شرط قرارش بدهید :
if (con.State == ConnectionState.Closed)
{
con.Open();
}
i = (int)com.ExecuteScalar();
con.Close();
private void btsabt_Click(object sender, EventArgs e)
{
if (tbName.Text.Trim() == string.Empty)
{
MessageBox.Show("نام مشتری الزامی می باشد", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
var con = new SqlConnection( Properties.Settings.Default. DB1ConnectionString);
var com = new SqlCommand("SELECT COUNT(*) FROM [tb-moshtari] WHERE [name moshtari]=@Name", con);
com.Parameters.Add( new SqlParameter("Name", tbName.Text));
if (con.State == ConnectionState.Closed)
{
con.Open();
}
var i = (int)com.ExecuteScalar();
con.Close();
if (i > 0)
{
MessageBox.Show( "یک مشتری با این نام قبلا به ثبت رسیده است", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
if (tb_moshtariTableAdapter1. InsertQuery( tbName.Text, tbtell.Text, tbMobile.Text, tbAdres.Text) > 0)
{
MessageBox.Show("ثبت شد");
Close();
}
else
{
MessageBox.Show("نام مشتری را کامل کنید");
}
}