Delphi DataSnap TJSONInterceptor for Variant don't revert correctly

318 Views Asked by At

I have DataSnap Server and I have some server method to Set and Get object with variant fields

here is a n example of object I can access via DataSnap :

type
  TOrder = class
  private
    [JSONReflect(ctObject, rtObject, TSampleVariantInterceptor, nil, true)]
    FComment: Variant;
    [JSONReflect(ctObject, rtObject, TSampleVariantInterceptor, nil, true)]
    FNumber: Variant;
    procedure SetComment(const Value: Variant);
    procedure SetNumber(const Value: Variant);

  public
    property Number: Variant read FNumber write SetNumber;
    property Comment: Variant read FComment write SetComment;
  end;

implementation

{ TOrder }

procedure TOrder.SetComment(const Value: Variant);
begin
  FComment := Value;
end;

procedure TOrder.SetNumber(const Value: Variant);
begin
  FNumber := Value;
end;

here is my ServerMethod sample code :

TsmOrder = class(TDSServerModule)
public
...
    function GetOrder(const AID: Integer): TOrder;
    function SetOrder(const AOrder: TOrder): Integer;
end;

here is my unit for where is defined my TSampleVariantInterceptor

unit MarshallingUtils;
    
    interface
    
    uses SysUtils, Classes, DBXJSON, StrUtils, RTTI, DBXJSONReflect, Variants;
        
        type
          TSampleVariantInterceptor = class(TJSONInterceptor)
          private
          public
            function ObjectConverter(Data: TObject; Field: String): TObject; override;
            procedure ObjectReverter(Data: TObject; Field: String; Arg: TObject); override;
          end;
        
          [JSONReflect(true)]
          TReflectVariantObject = class
          private
            FType: TVarType;
            FValue: string;
          public
            constructor Create(ASampleVariant: Variant);
            function GetVariant: Variant;
          end;
        
        implementation
          
        const
          NullVariantString = 'null';
        
        { TSampleVariantInterceptor }
        
        function TSampleVariantInterceptor.ObjectConverter(Data: TObject;
          Field: String): TObject;
        var
          LRttiContext: TRttiContext;
          LVariant: Variant;
        begin
          LVariant := LRttiContext.GetType(Data.ClassType).GetField(Field).GetValue(Data).AsType<Variant>;
          Result := TReflectVariantObject.Create(LVariant);
        end;
        
        procedure TSampleVariantInterceptor.ObjectReverter(Data: TObject; Field: String;
          Arg: TObject);
        var
          LRttiContext: TRttiContext;
          LRttiField: TRttiField;
          LVariant: Variant;
        begin
          Assert(Arg is TReflectVariantObject);
          LVariant := TReflectVariantObject(Arg).GetVariant;
          LRttiField := LRttiContext.GetType(Data.ClassType).GetField(Field);
          LRttiField.SetValue(Data, TValue.FromVariant(LVariant));
          Arg.Free;
        end;
        
        { TReflectVariantObject }
        
        constructor TReflectVariantObject.Create(ASampleVariant: Variant);
        begin
          FType := VarType(ASampleVariant);
          case FType of
            varNull: FValue := NullVariantString;
          else
            FValue := ASampleVariant; // Convert to string
          end;
        end;
        
        function TReflectVariantObject.GetVariant: Variant;
        var
          V: Variant;
        begin
          if FValue = NullVariantString then
            V := Null
          else
            V := FValue;
          VarCast(Result, V, FType);
        end;
        
        end.

My variant is well converted in my server : I can't see the null string in fiddler but in my client application my variant appear to Empty instead of Null Variant. Do I make something wrong ?

0

There are 0 best solutions below