View Full Version : سوال: چگونه استثناء در زمان اتصال به سرور Datasnap را هندل کنیم؟
hp1361
دوشنبه 26 فروردین 1392, 07:20 صبح
با سلام
من با کد زیر استثناء در زمان اتصال به سرور Datasnap رو هندل میکنم
procedure TForm2.btn_1Click(Sender: TObject);
begin
try
ClientModule1.SQLConnection1.Open;
except
on E: TDBXError do
begin
if (e.errorcode=TDBXErrorCodes.AuthorizationFailed) then
ShowMessage('hello');
end;
end;
end;
و نام کاربری رو عمدا اشتباه وارد میکنم اما چیزی که برمیگردونه مقدار None=0 هستش در حالیکه انتظار AuthorizationFailed=113 رو دارم!. حالا اگر دستور نمایش پیام ارور رو بدم ، پیغام به صورت زیر هستش!
102857
مشکل کجاست و چطور بتونم مدیریتش کنم؟
ممنون
پ.ن: در زمان نوشتن این کدا اشتباها AuthorizationFailed رو AuthenticationFailed می خوندم و انتظار هندل داشتم! و فکر میکردم باید کد 113 برگردونه در حالیکه کد 0 بر میگردوند و کد 0 برابر با None بود.
tomalaki
چهارشنبه 28 فروردین 1392, 21:10 عصر
منم همین مشکل رو دارم
BORHAN TEC
پنج شنبه 29 فروردین 1392, 11:47 صبح
سلام
واقعاً یادم رفت که این تاپیک رو بررسی کنم.
برای مدیریت کردن قضایایی از این دست قبلاً آقای andreano lanusse روشی را در لینک زیر توضیح داده بودند(برای مشاهده باید از روشهای غیر رایج استفاده کنید!):
http://www.andreanolanusse.com/en/datasnap-2010-authentication-throught-tcpip-transport/
hp1361
پنج شنبه 29 فروردین 1392, 14:53 عصر
سلام
خوب وقتی پیام بالا نمایش داده میشه آیا به این معنی نیست که یک Exception از سمت سرور به سمت کلاینت ارسال شده؟
اگه آره چرا پس نمیتونم هندلش کنم؟
اگه نه پس این پیغام برا چیه؟
ممنون
BORHAN TEC
جمعه 30 فروردین 1392, 02:07 صبح
سلام
خوب وقتی پیام بالا نمایش داده میشه آیا به این معنی نیست که یک Exception از سمت سرور به سمت کلاینت ارسال شده؟
دقیقاً همینطوره
اگه آره چرا پس نمیتونم هندلش کنم؟
اگه نه پس این پیغام برا چیه؟
:متعجب:، در یک مورد خاص اینقدر سوال عجیب و غریب می پرسید که آدم هنگ میکنه چی رو باید جواب بده! :لبخند:
اینطوری نمیشه، باید یک مثال بزنم. در مواقعی شما نیاز دارید که بنا به شرایط پیش آمده یک ErrorCode رو از برنامه سرور به یک کلاینت ارسال کنید. کلاس TDBXError طوری پیاده سازی شده که میتونه یک ErrorCode رو هم شامل بشه(بهتره که به پیاده سازیش نگاهی بیاندازید). نیازی نیست که حتماً از کلاس TDBXError استفاده کنید بلکه خودتان می توانید یک کلاس استثنا را با ساختاری شبیه آن و با نام دیگری بسازید و ازش استفاده کنید. در یک مثال ساده در زیر نحوه فرستان کد خطا از سرور به کلاینت را نشان داده ام.
برای نمونه این کد ساده را در رویداد OnUserAuthenticate کامپوننت DSAuthenticationManager در برنامه سرور بنویسید:
procedure TServerContainer1.DSAuthenticationManager1UserAuth enticate
(Sender: TObject; const Protocol, Context, User, Password: string;
var valid: Boolean; UserRoles: TStrings);
begin
valid := False;
if User = 'ali' then
valid := True
else
raise TDBXError.Create(113, 'نام کاربری و/یا رمز عبور اشتباه است');
end;
حالا در سمت کلاینت از کدی مثل کد زیر استفاده کن و یه فاتحه برای اموات ما بخون(!): :چشمک: :لبخندساده:
procedure TForm2.Button1Click(Sender: TObject);
begin
try
ClientModule1.SQLConnection1.Params.Values['DSAuthenticationUser'] := 'MyInvalidUser!';
ClientModule1.SQLConnection1.Open;
except
on E: TDBXError do
ShowMessage(IntToStr(E.ErrorCode));
end;
end;
موفق باشید...
hp1361
جمعه 30 فروردین 1392, 08:23 صبح
سلام
بسیار ممنون از پاسخ و صبر و حوصله شما
با مثال شما من خیلی ذهنم بازتر شد. البته اگه بخاطر بیارید من در مورد استفاده از یک وب سرویس خاص خیلی مشکل داشتم که یجورایی با چیزی مثل مثال شما قبلا حلش کردم.
مشکل الان من اینه که این استثنائی که الان از سمت سرور داره میاد(تصویر بالا) مگه این نیست؟
AuthorizationFailed
اگه اره پس چرا کد ارور 0 برمیگردونه
اگه نه یعنی برای این ارور کدی نزاشتن برادرای Embarcadero؟
ممنون
BORHAN TEC
جمعه 30 فروردین 1392, 10:31 صبح
سلام
البته اگه بخاطر بیارید من در مورد استفاده از یک وب سرویس خاص خیلی مشکل داشتم که یجورایی با چیزی مثل مثال شما قبلا حلش کردم.
متاسفانه به خاطر نمیارم. :ناراحت:
مشکل الان من اینه که این استثنائی که الان از سمت سرور داره میاد(تصویر بالا) مگه این نیست؟...
نه، Authentication با Authorization فرق داره! اگه به صورت ساده بخوام بگم Authorization زیر مجموعه ای از Authentication است. اگر شما اجازه ورود به یک خانه را داشته باشید به این میگن Authentication . اینکه شما اجازه ورود به اتاق های خانه را داشته باشید یا نه بحث Authorization پیش میاد. به کلام ساده برای رسیدن به مرحله Authorization باید ابتدا از مرحله Authentication عبور کرده باشیم. این فرق بین این دو بود در حالت کلی! :چشمک:
اگه اره پس چرا کد ارور 0 برمیگردونه
اگه نه یعنی برای این ارور کدی نزاشتن برادرای Embarcadero؟
این که عدد 0 رو برمیگردونه برای من هم کمی عجیبه. در هر صورت من در این مورد هنوز راه حل دیگری را پیدا نکرده ام و بعید هم میدانم فعلاً بجز راه حلی که ارائه کردم راه حل دیگری وجود داشته باشد. اگر شما راه حل دیگری پیدا کردید من خوشحال می شوم که اطلاع دهید.
موفق باشید...
hp1361
جمعه 30 فروردین 1392, 12:00 عصر
سلام
اشتباه از من بود.وقتی در قسمت Authorization ورودی رو اشتباه وارد کردم Exception هندل شد.
اما کماکان با این Authentication مشکل پابرجاست!
چرا برای Authorization کد ارور تعریف کردن اما برای Authentication نه؟
البته از اونجایی که پیغام ارسال میشه پس تعریف کردن اما اینکه چرا کدش صفره من نمیدونم!
فقط به من بگید چطور بفهمم این 113 از کجا اومده و پیغامش توی کدوم یونیته.(وقتی از تابعی که اوتورایز نشده برای کاربر استفاده کنم این کد پس میده)
ممنون
hp1361
جمعه 30 فروردین 1392, 12:16 عصر
سلام مجدد
خودم گشتم و اینارو پیدا کردم
اول این
procedure TDSServer.Connecting(const ConnectEventObject: TDSConnectEventObject);
var
LDSSession: TDSSession;
begin
LDSSession := TDSSessionManager.GetThreadSession;
if LDSSession <> nil then
if not LDSSession.Authenticate(ConnectEventObject.ServerC onnectionHandler.AuthenticateEventObject,
ConnectEventObject.ConnectProperties) then
raise TDBXError.Create(0, SAuthenticationFailed);
if Assigned(FConnectEvent) then
FConnectEvent(ConnectEventObject);
end;
یعنی اگه Authenticate نشه این SAuthenticationFailed باید رخ بده!که داریم:
SAuthenticationFailed = 'Authentication manager rejected user credentials. This may due to invalid combination of DS user name and password';
اما در بخش تعریف کد برای ارور ها اینو باز داریم:
/// <summary>Error codes for DBXError exceptions</summary>
TDBXErrorCodes = class
const
///<summary>Successful completion.</summary>
None = $0000;
یعنی صفر هم برای None تعریف شده و هم برای SAuthenticationFailed
آیا این باگ نیست؟ یا برداشت من اشتباهِ ؟
BORHAN TEC
جمعه 30 فروردین 1392, 19:00 عصر
سلامی مجدد
آیا این باگ نیست؟ یا برداشت من اشتباهِ ؟
برداشت شما اشتباه نیست. به نظر من هم بهتر بود که یک کد خطای منحصر به فرد هم برای Authentication تعریف می کردند، چون کد خطای 0 زیاد مناسب این کار نیست. سعی می کنم که این مورد را گزارش کنم.
tomalaki
جمعه 30 فروردین 1392, 21:11 عصر
ShowMessage(IntToStr(E.ErrorCode));
با این دستور کد 113 رو نشون میده. من از E.Message استفاده کردم درست شد. اما یه Remote Error هم ظاهر شده. نمیشه کاریش کرد اونم نباشه؟ :لبخندساده:
103074
BORHAN TEC
جمعه 30 فروردین 1392, 21:40 عصر
با این دستور کد 113 رو نشون میده. من از E.Message استفاده کردم درست شد. اما یه Remote Error هم ظاهر شده. نمیشه کاریش کرد اونم نباشه؟
شما به ساختار Case اعتقاد دارید؟! :چشمک:
procedure TForm2.Button1Click(Sender: TObject);
begin
try
ClientModule1.SQLConnection1.Params.Values['DSAuthenticationUser'] := 'MyInvalidUser!';
ClientModule1.SQLConnection1.Open;
except
on E: TDBXError do
Case E.ErrorCode of
113: ShowMessage('نام کاربری و/یا رمز عبور اشتباه است');
end;
end;
end;
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.