LoginService - UserInfo

Hi

Using D12.2 & RODA 10.0.0.1605 - Code First service(s)

Having a LoginService (TSimpleLoginService) and a OnLogin event.

  [ROService(SvcLogin, SvcLoginID)]
  [RONamespace(__RODLLibraryNamespace)]
  [ROStandardClassFactory]
  TServiceLogin = class(TSimpleLoginService)
    procedure OnLoginServiceLogin(Sender: TObject; aUserID,
      aPassword: ROUTF8String; out aUserInfo: UserInfo;
      var aLoginSuccessful: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  published
    [ROServiceMethod]
    function Login([ROStreamAs(emUTF8)] const aUserID: ROUTF8String; [ROStreamAs(emUTF8)] const aPassword: ROUTF8String; out aUserInfo: UserInfo): Boolean; override;
    { Published declarations }
  end;

Having the UserInfo extended as

  CQUserInfo = class(DataAbstract4_Intf.UserInfo)
  private
    FLanguageApp: ROUTF8String;
    FLanguageData: ROUTF8String;
    FLastName: ROUTF8String;
    FFirstName: ROUTF8String;
    FLogin: ROUTF8String;
  published
    property LanguageApp: ROUTF8String read FLanguageApp write FLanguageApp;
    property LanguageData: ROUTF8String read FLanguageData write FLanguageData;
    property Login: ROUTF8String read FLogin write FLogin;
    property FirstName: ROUTF8String read FFirstName write FFirstName;
    property LastName: ROUTF8String read FLastName write FLastName;
  end;

The OnLoginEvent is implemented this way (edited):

procedure TServiceLogin.OnLoginServiceLogin(Sender: TObject; aUserID,
  aPassword: ROUTF8String; out aUserInfo: UserInfo;
  var aLoginSuccessful: Boolean);
var
  aCQUser: CQUserInfo;
  aLoginUser: TLoginUser;
  sPrivileges: string;
  iCnt: Integer;
begin
  aLoginSuccessful := aLoginUser.IsLoggedIn;

  if aLoginSuccessful then
  begin
    aCQUser := CQUserInfo.Create;
    aCQUser.SessionID := GuidToString(Session.SessionID);
    aCQUser.UserID := IntToStr(aLoginUser.ID);
    aCQUser.FirstName := aLoginUser.FirstName;
    aCQUser.LastName := aLoginUser.LastName;
    aCQUser.Login := aLoginUser.Login;
    aCQUser.LanguageApp := aLoginUser.LanguageApp;
    aCQUser.LanguageData := aLoginUser.LanguageData;

    DoGetPrivileges(aCQUser);

    aUserInfo := aCQUser;
  end;
end;

Clientside the loginservice is called

var
  aUserInfo: UserInfo;

ServiceLogin.Login(edtUser.Text, edtPassword.Text, aUserInfo)

This results in an error


while serializing.

Tried a different approach with a MyLogin method returning a CQUserInfo instead of a UserInfo. Same error.
Returning a ‘regular’ UserInfo works fine.

What is wrong or what am I doing wrong?

Regards,
Filip

Hi,

in your case, when CodeFirst-based object is inherited from RODL-based object, you should implement own ReadComplex/WriteComplex methods otherwise UserInfo.ReadComplex & UserInfo.WriteComplex will be used by default …


use TROComplexType implementation for your CodeFirst-based object

procedure TROComplexType.ReadComplex(ASerializer: TObject);
begin
  ReadObjectFromSerializer(TROSerializer(ASerializer), Self);
end;

procedure TROComplexType.WriteComplex(ASerializer: TObject);
begin
  WriteObjectToSerializer(TROSerializer(ASerializer), Self);
end;

i.e.

procedure CQUserInfo.ReadComplex(ASerializer: TObject);
begin
  ReadObjectFromSerializer(TROSerializer(ASerializer), Self);
end;

procedure CQUserInfo.WriteComplex(ASerializer: TObject);
begin
  WriteObjectToSerializer(TROSerializer(ASerializer), Self);
end;

Hi,

fyi: I’ve added DefaultReadComplex/DefaultWriteComplex methods to TROComplexType.

procedure TROComplexType.DefaultReadComplex(ASerializer: TObject);
begin
  ReadObjectFromSerializer(TROSerializer(ASerializer), Self);
end;

procedure TROComplexType.DefaultWriteComplex(ASerializer: TObject);
begin
  WriteObjectToSerializer(TROSerializer(ASerializer), Self);
end;

procedure TROComplexType.ReadComplex(ASerializer: TObject);
begin
  DefaultReadComplex(ASerializer);
end;

procedure TROComplexType.WriteComplex(ASerializer: TObject);
begin
  DefaultWriteComplex(ASerializer);
end;
1 Like