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 ?