Login with custom UserInfo in client (code-first)

Hi

I have a problem whose I don’t understand cause.

I defined a login service (code-first) with a custom UserInfo class that I send to client when the login is successful.

var
  LUserInfoEx: TUserInfoEx;
begin
  LUserInfoEx := ValidateUser(AUserID, APassword);

  ALoginSuccessful := Assigned(LUserInfoEx); // AUserID = APassword;

  if ALoginSuccessful then
  begin
    LoadWardsUser(LUserInfoEx.PKUser, LUserInfoEx.Wards);

    AUserInfo := LUserInfoEx; 
    AUserInfo.SessionID := GuidToString(ClientID);
    AUserInfo.UserID := AUserID;

    Session['UserID'] := AUserID;
    Session['PKUser'] := LUserInfoEx.PKUser;
    try
      LoginUser(LUserInfoEx.PKUser, FClientAddess);
    except
      // DestroySession;
      LogoutUser;
      raise;
    end;
  end
  else
  begin
    LogoutUser;
  end;

The function ValidateUser check the username and password and if ok create the TUserInfoEx class and load the all data.

  Result := TUserInfoEx.Create;
  Result.PKUser := LUserDataSet.FieldByName('Pkpersonale').AsInteger;
  Result.FirstName := LUserDataSet.FieldByName('Nome').AsString;
  Result.LastName := LUserDataSet.FieldByName('Cognome').AsString;
  Result.FiscalCode := LUserDataSet.FieldByName('CodiceFiscale').AsString;
  Result.IsAdmin := LUserDataSet.FieldByName('IsAdmin').AsInteger = 1;
  Result.IsSuperUser := LUserDataSet.FieldByName('Superuser').AsInteger = 1;
  Result.IsInternal := LUserDataSet.FieldByName('IsInternal').AsInteger = 1;
  Result.DatePasswordExpiration := LUserDataSet.FieldByName('ScadenzaPwd').AsDateTime;
  Result.DateLastChengedPassword := LUserDataSet.FieldByName('ModPassword').AsDateTime;
  Result.ChangePassword := (LUserDataSet.FieldByName('CambiaPwd').AsInteger = 1) or
    (LUserDataSet.FieldByName('ScadenzaPwd').AsDateTime > Now) or
    (LUserDataSet.FieldByName('ScadenzaPwd').AsDateTime = 0) or
    (IncDay(LUserDataSet.FieldByName('ModPassword').AsDateTime, LUserDataSet.FieldByName('ValiditaPwd').AsInteger) > Now);
  Result.ResetPassword := LUserDataSet.FieldByName('ResetPswd').AsInteger = 1;
  Result.Email := LUserDataSet.FieldByName('Email').AsString;
  Result.RequiredPIN := LUserDataSet.FieldByName('RichiediPin').AsInteger = 1;
  Result.RegistrationNumber := LUserDataSet.FieldByName('Matricola').AsString;
  Result.VocalProfile := LUserDataSet.FieldByName('ProfiloVocale').AsString;
  Result.AllowOverbooking := LUserDataSet.FieldByName('AllowOverbooking').AsInteger = 1;
  Result.SelectedWardIndex := -1;

Server side work all!

In client side when i try to call the login method the generated unit _int raise an exception when load the TUserInfoEx class.

image

image

This is the code into uROSerializer unit

image

and this teh procedure ReadUnicodeString into uROStreamSerializer

The problem is in the sze integer var. The value is : 1127301421. why is it so big?

The initial project was developed with rodl, while now I’m rewriting it in code-first (starting a new project), and I had never experienced this problem before.

Any help?

Hi,

looks like some fields were serialized incorrectly.
this may happen when non-standard RODL datatype like Word, Byte, etc are used.
I need a testcase that reproduces this error.
you can send it to support@ for keeping privacy

Hi EvgenyK

it’s not easy but I create it and send it to you by email

Many thanks

Hi,

just create a server method that returns your struct that causes failure on client-side.
it will be easier than creating a full functionality DA Server …

Hi EvegnyK

I created the sample by my real project and removed all code that access to DB.

I send email to support@ …

Many thanks!!

Hi,

your issue - you have used class declared in RODL as ancestor and didn’t override ReadComplex&WriteComplex methods, i.e. rules how to serialize/deserialize data.
as a result, your class used rules from UserInfo that only reads/writes 5 fields declared in UserInfo.

workaround: return original behavior of TROComplexType, i.e.

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

procedure TUserInfoEx.WriteComplex(aSerializer: TObject);
begin
  WriteObjectToSerializer(TROSerializer(ASerializer),Self);
end;
1 Like