نحوه پاس دادن خطا در برنامه نویسی لایه ای
با سلام
من تو پروژه ام از برنامه نویسی لایه ای استفاده کردم . حالا میخام بدونم چطوری میشه اگه خطایی تو sql اتفاق افتاد رو به کاربر نشون بدم . با Try Catch فقط این کارو انجام دادم " تشخیص اینکه ایا خطایی رخ داده یا نه " . ولی اینکه اون چه خطایی بوده و متن اون خطا چیه و چطور به کاربر نشون بدم رو دیگه نمیدونم . ممنون میشم از دوستان کمک کنن.
با تشکر
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
سلام.
میتونید اینطور بنویسید:
try
{
// کدهای اصلی برنامه
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
خطاهایی که در sql رخ میدن :
try
{
// کدهای اصلی برنامه
}
catch(SqlException ex)
{
MessageBox.Show(ex.Message);
}
موفق باشید.
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
ببینید متن خطای Sql بدرد کاربر نمیخوره، شما میتونی، با همون try-catch، خطای نوع SqlException رو catch کنید، و با بررسی مشخصات شئ Exception، متن خطایی که برای کاربر قابل فهم باشه رو بهش نشون بدی، علاوه بر اون امکانی بگذاری، که مشخصات این SqlException رو یا جایی ذخیره کنید، یا e-mail بشه بهتون.و البته میتونید برای دم دست بودن به کاربر هم نشون بدین (با گذاشتن مثلا قابلیت کپی) ولی برای نمایش به کاربر به متن انگلیسی خطا اکتفا نکنید.
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
ممنون از جوابتون . حالا سوال من اینه که چطور خود Exception رو از لایه Dal به Bll و در نهایت به Ui ارسال کنم . منظورم اینه که باید متد جداگونه ای بنویسم که اگه خطا داشتیم کنترل اجرا به اون واگزار بشه یا .... ؟
یه چیزی در مورد EventLog دیدم ولی نمیدونم درسته یا نه و اصلا چطور باید باهاش کار کرد .
ممنون
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
نقل قول:
نوشته شده توسط
saeed zarei
ممنون از جوابتون . حالا سوال من اینه که چطور خود Exception رو از لایه Dal به Bll و در نهایت به Ui ارسال کنم . منظورم اینه که باید متد جداگونه ای بنویسم که اگه خطا داشتیم کنترل اجرا به اون واگزار بشه یا .... ؟
یه چیزی در مورد EventLog دیدم ولی نمیدونم درسته یا نه و اصلا چطور باید باهاش کار کرد .
ممنون
بله شما در لایههای پایینتر باید خطا را تولید کنید و در آخرین لایه یعنی لایه UI در صورت بروز خطا پیغام مناسب بدهید
با دستور throw new exption
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
هندل کردن Exception ها باید تو سطح کل نرم افزار یه فکری براش بشه، نه فقط لایه DAL و ... . بسته به نیاز، کارهای مختلفی میشه کرد.
میتونین همونطور که گفتم متن مناسب فارسی و متن خطا و... رو در بیارین و در قالب یک شئ مثلا DALException:Exception در پایین ترین لایه throw کنید.این expcetion رو میتونید توی UI با گذاشتن یک try catch هندل کنید و یا در رویداد Application.ThreadException .
.ٍEvent logs هم روشی هست که برای ثبت خطاها، رویدادها و ...در ویندوز پیاده شده. پیشنهاد میکنم از اون استفاده نکید و روشی داشه باشید که مجزا اطلاعات خطا رو روی فایل یا جای دیگه ذخیره کنه.
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
برای log کردن از log4net استفاده کنید...
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
میشه خواهش کنم بیشتر توضیح بدید
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
نقل قول:
نوشته شده توسط
saeed zarei
میشه خواهش کنم بیشتر توضیح بدید
از کدهایی که نوشتی برای مثال از هر لایه یک کلاس بگذار تا روی آنها توضیج بدهم
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
منون میشم تا انتها کمکم کنید .
این قطعه کد مربوط به لایبراری DAL و کلاس Base هست :
public SqlDataReader ExecuteReaderWitParameters(out SByte result, CommandType commandType, string commandText, SqlParameter[] commandParameters)
{
SqlConnection con = new SqlConnection(ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = commandType;
cmd.CommandText = commandText;
cmd.Parameters.AddRange(commandParameters);
bool mustCloseConnection = false;
try
{
if (con.State != ConnectionState.Open)
{
mustCloseConnection = true;
con.Open();
}
else
{
mustCloseConnection = false;
}
dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection) ;
result = 100;
return dataReader;
}
catch
{
if (mustCloseConnection)
con.Close();
dataReader = null;
result = -100;
return dataReader;
}
}
این هم مربوط به لایبراری DAL و کلاس Total:
public SqlDataReader GetAllPrivateTotal(out sbyte result, string start)
{
return ExecuteReaderWitParameters(out result, CommandType.StoredProcedure, "S_All_Private_Total", new SqlParameter[] {
new SqlParameter ("@start" , start)});
}
اینم کد مربوط به لایبراری BLL و کلاس Total :
public static List<Total> GetAllPrivatTotal(out sbyte result, string start)
{
DAL_Acc_Fakke.Total dalTotal = new DAL_Acc_Fakke.Total();
IDataReader idrTotal = dalTotal.GetAllPrivateTotal(out result,start);
if (result == 100)
{
List<Total> totalList = new List<Total>();
while (idrTotal.Read())
{
Total tempTotal = new Total();
tempTotal.Text = idrTotal["Text"].ToString();
totalList.Add(tempTotal);
}
return totalList;
}
return null;
}
من چون نمیدونستم باید چطور این کار رو انجام بدم اومدم از یک آرگومان به نام Result استفاده کردم و اگه اون برابر با -100 بود یعنی کدم خطا داشته . حالا باید چی کار کنم . بی زحمت یه کم کامل توضیح بدید .
ممنون و تشکر از وقتی که گذاشتید
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
کلا کد نویسی تون عجیب و غریب هست. شما لایه dal را بی جهت تا bll گسترش دادید.
به هر حال
در bll اگر result==-100 باشد فکر کنم باید می نوشتید.
در try قسمت catch این جور بنویسید
catch (exception ex)
throw new exception("خطا در واکشی داده ها",ex)
در bll هم همین طورهمین کد را تکرار کنید و در انتها در لایه نمایش
در try در قسمت catch مثلا از یک messagebox استفاده کنید تا خطا را به کاربر نمایش دهید.
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
سلام . ممنون از راهنماییتون . من کد رو به صورتی که گفتید درست کردم و جواب هم گرفتم . حالا نکته دیگه ای در این مورد هست که بگید ؟
و دیگه اینکه من چطور میتونم بفهمم چه خطایی اتفاق افتاده که پیغام فارسی معادل اونو به کاربر نشون بدم ؟(لطفا تو این زمینه به صورت کامل کمکم کنید . ممنون)
در اخر شما گفتید که
نقل قول:
کلا کد نویسی تون عجیب و غریب هست. شما لایه dal را بی جهت تا bll گسترش دادید.
میشه در این مورد هم یه کم توضیح بدید . چون من همه پروژه هامو دارم به همین صورت مینویسم .
خدا خیرتون بده .
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
نقل قول:
نوشته شده توسط
saeed zarei
سلام . ممنون از راهنماییتون . من کد رو به صورتی که گفتید درست کردم و جواب هم گرفتم . حالا نکته دیگه ای در این مورد هست که بگید ؟
و دیگه اینکه من چطور میتونم بفهمم چه خطایی اتفاق افتاده که پیغام فارسی معادل اونو به کاربر نشون بدم ؟(لطفا تو این زمینه به صورت کامل کمکم کنید . ممنون)
در اخر شما گفتید که
میشه در این مورد هم یه کم توضیح بدید . چون من همه پروژه هامو دارم به همین صورت مینویسم .
خدا خیرتون بده .
خوب یک exception خودتان بسازید با ارث بری از کلاس exception یک کمی پر و بالش بدهید مثلا براش errorCode را بصورت پروپرتی تعریف کنید. یک چیزی شبیه این اونجایی که throw میکنید اطلاعات بشتر به پروپرتیهای بدهید.
بعد در لایه UI یک فرم طراحی کنید که برای نمایش این خطا ها باشه بجای msgbox از این فرم استفاده کنید. شما شروع کنید من کمکتون میکنم.
در مورد کدهاتون
شرایط ایدهال این هست که از or mapper استفاده کنید که فعلا بهترین ها Entity Framework , NHibernate هست. یک کمی باید مطالعه کنید در موردشون مخصوصا انتیتی فریمورک.
در حالتی که شما مستقیم با ADO.net کار میکنید. شما همین Total را باید در لایه DAL برگردانید. ولی نوع توتال باید در همان بیزینس تعریف شود در بیزینس نباید کدهای مربوط به واکشی دادهها وجود داشته باشد اصطلاحا نباید ارجایی به System.data داشته باشید.
دوست داشتید میتوانید سر فرصت کدهای شما را بررسی کنیم
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
ممنون از اینکه دارید وقت میزارید .
راستش تازه دارم با EF کار میکنم ، و خیلی بلد نیستم و دیگه اینکه تقریبا نیمی از پروژه ای که دارم مینویسم رو با برنامه نویسی لایه ای انجام دادم . من کدهام رو به این صورت که شما گفتید نوشتم ولی خطایی مبنی بر اینکه باید لایبراری Dal رو هم به پروژه ارجاع بدید بهم داد :
این مربوط به لایبراری DAL و کلاس Base
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
namespace dal
{
public class BaseDal
{
public SqlDataReader ExecuteReaderNoParameters(CommandType commandType, string commandText)
{
SqlConnection con = new SqlConnection(ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = commandType;
cmd.CommandText = commandText;
bool mustCloseConnection = false;
try
{
if (con.State != ConnectionState.Open)
{
mustCloseConnection = true;
con.Open();
}
else
mustCloseConnection = false;
SqlDataReader dr;
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection) ;
return dr;
}
catch (Exception ex)
{
if (mustCloseConnection)
con.Close();
dataReader = null;
throw new Exception("Can Not Connect.", ex);
}
}
}
}
این چندتا هم مربوط به لایبراری DAL و کلاس Total
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
namespace dal
{
public class Total : BaseDal
{
public string Text { get; set; }
private SqlDataReader GetAllTotal()
{
try
{
return ExecuteReaderNoParameters(CommandType.StoredProced ure, "S_All_Total");
}
catch (Exception ex)
{
throw new Exception("Can Not Connect.", ex);
}
}
public SqlDataReader GetAllPrivateTotal(out sbyte result, string start)
{
return ExecuteReaderWitParameters(out result, CommandType.StoredProcedure, "S_All_Private_Total", new SqlParameter[] {
new SqlParameter ("@start" , start)});
}
public List<Total> GetListAllTotal()
{
try
{
Total dalTotal = new Total();
IDataReader idrTotal = GetAllTotal();
List<Total> totalList = new List<Total>();
while (idrTotal.Read())
{
Total tempTotal = new Total();
tempTotal.Text = idrTotal.GetValue(1).ToString();
totalList.Add(tempTotal);
}
return totalList;
}
catch (Exception ex)
{
throw new Exception("Can Not ... ", ex);
}
}
}
}
و در نهایت :
private void btnShow(object sender, EventArgs e)
{
dgv.DataSource = BTotal.GetAllTotal();
}
مگه در برنامه نویسی لایه ای هر لایه فقط به لایه بالاتر از خودش سرویس نمیده ؟
یعنی Dal --> Bll -->UI
پس در bll یه ارجاع به Dal ، و در UI هم فقط باید یه ارجاع به Bll داشته باشیم .
برای کلاس Exception هم که گفتید ، چشم من شروع میکنم و خواهشم اینه که کمک کنید .
با تشکر
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
اقای بابک بخشایش (Linux) چی شد ؟
نقل قول: نحوه پاس دادن خطا در برنامه نویسی لایه ای
نقل قول:
نوشته شده توسط
saeed zarei
ممنون از اینکه دارید وقت میزارید .
راستش تازه دارم با EF کار میکنم ، و خیلی بلد نیستم و دیگه اینکه تقریبا نیمی از پروژه ای که دارم مینویسم رو با برنامه نویسی لایه ای انجام دادم . من کدهام رو به این صورت که شما گفتید نوشتم ولی خطایی مبنی بر اینکه باید لایبراری Dal رو هم به پروژه ارجاع بدید بهم داد :
این مربوط به لایبراری DAL و کلاس Base
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
namespace dal
{
public class BaseDal
{
public SqlDataReader ExecuteReaderNoParameters(CommandType commandType, string commandText)
{
SqlConnection con = new SqlConnection(ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = commandType;
cmd.CommandText = commandText;
bool mustCloseConnection = false;
try
{
if (con.State != ConnectionState.Open)
{
mustCloseConnection = true;
con.Open();
}
else
mustCloseConnection = false;
SqlDataReader dr;
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection) ;
return dr;
}
catch (Exception ex)
{
if (mustCloseConnection)
con.Close();
dataReader = null;
throw new Exception("Can Not Connect.", ex);
}
}
}
}
این چندتا هم مربوط به لایبراری DAL و کلاس Total
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
namespace dal
{
public class Total : BaseDal
{
public string Text { get; set; }
private SqlDataReader GetAllTotal()
{
try
{
return ExecuteReaderNoParameters(CommandType.StoredProced ure, "S_All_Total");
}
catch (Exception ex)
{
throw new Exception("Can Not Connect.", ex);
}
}
public SqlDataReader GetAllPrivateTotal(out sbyte result, string start)
{
return ExecuteReaderWitParameters(out result, CommandType.StoredProcedure, "S_All_Private_Total", new SqlParameter[] {
new SqlParameter ("@start" , start)});
}
public List<Total> GetListAllTotal()
{
try
{
Total dalTotal = new Total();
IDataReader idrTotal = GetAllTotal();
List<Total> totalList = new List<Total>();
while (idrTotal.Read())
{
Total tempTotal = new Total();
tempTotal.Text = idrTotal.GetValue(1).ToString();
totalList.Add(tempTotal);
}
return totalList;
}
catch (Exception ex)
{
throw new Exception("Can Not ... ", ex);
}
}
}
}
و در نهایت :
private void btnShow(object sender, EventArgs e)
{
dgv.DataSource = BTotal.GetAllTotal();
}
مگه در برنامه نویسی لایه ای هر لایه فقط به لایه بالاتر از خودش سرویس نمیده ؟
یعنی Dal --> Bll -->UI
پس در bll یه ارجاع به Dal ، و در UI هم فقط باید یه ارجاع به Bll داشته باشیم .
برای کلاس Exception هم که گفتید ، چشم من شروع میکنم و خواهشم اینه که کمک کنید .
با تشکر
حرفتون درست هست این وسط اصطلاحی به اسم بیزینس آبجکتها داریم که بین همه لایه ها مشترک هستند. مثل همین آبجکت توتال. شما یک آبجکتی به اسم توتال دارید حالا اینجا فقط یک استرینگ هست ممکن مثلا اطلاعات مربوط به یک شخص باشه یک کلاس تعریف کنید که فقط پروپرتی داشته باشه .