TXDataJsonServerDeserializer, IJsonReferenceSolver, TServerReferenceSolver

Hello Wagner,

I want to use XData serializer and deserializer, because I have Entities with references. The other converter don't work. (Aurelius don't delete the "F")

In the constructor I need a ReferenceSolver. I thought, it's easy, I search the XData directory. I found the TServerReferenceSolver, but it is in the implementation section and not in the interface section.
Whiý is it not public? Is there another Function? Do I have to create my own solver?

What is the easiest way to serialize/deserialize?

Best regards
Thomas

Actually I use (without references):

uses
  Rtti, Classes,
  Aurelius.Mapping.Explorer,
  XData.Aurelius.Model,
  xdata.Json.Deserializer,
  xdata.Json.Serializer;


type
  TsngJson = class
  public
    class function Serialize<T: class>(const ModelName: string; const Value: T): string;
    class function Deserialize<T: class>(const ModelName: string; const Json: string): T;


  end;

implementation

{ TsngJson }

class function TsngJson.Serialize<T>(const ModelName: string; const Value: T): string;
var
  Serializer: TXDataJsonServerSerializer;
begin
  Serializer := TXDataJsonServerSerializer.Create( TXDataAureliusModel.Get( ModelName));
  try
    Result := Serializer.Write(Value);
  finally
    Serializer.Free;
  end;
end;



class function TsngJson.Deserialize<T>(const ModelName: string;const Json: string): T;
var
  Deserializer: TXDataJsonserverDeserializer;

begin
  Deserializer := TXDataJsonserverDeserializer.Create( TXDataAureliusModel.Get( ModelName),nil);

  try
    Result := Deserializer.Read<T>(Json);
  finally
    Deserializer.Free;
  end;

  //Result := Deserialize(Json, TypeInfo(T)).AsType<T>;
end;

Is using it without a reference solve causing you any issue? It's used to load blob and proxy values, but the TServerReferenceSolver is very specific to the current XData context (request being processed).

It really depends on what you are using the JSON for.

I have some service functions that send entities over XData. E.g. a subscription to an event. My server gets the JSON data and the easiest way is to deserialize the data. But here is a reference (reference ID) that I need.

I'm currently doing it manually, but it would be easier to do it automatically. I have many similar functions.

Here is an example of how I read the "Event" field from a JSON data.
It might look like this: "Event":"{xxxx-xxxx}"
or like this: "Event@xdata.ref":"PubEvent(xxxxx-xxxxx)"

Depending on how it was serialized.

  // ** Event
  LValue := AJSONData.Values[ DicPub.PubSubscription.Event.AssociationName];
  if LValue = nil then begin
    // falls im JSON XData-Referenz angegeben ist, z.B. "Event@xdata.ref":"PubEvent(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
    LValue := AJSONData.Values[ DicPub.PubSubscription.Event.AssociationName + '@xdata.ref'];
    if LValue <> nil then begin
      strValue := LValue.AsType<String>;
      result.Event := AObjectManager.Find<TPubEvent>( DirtyStringToGuid( '{' +  copy( strValue, Pos( '(', strValue) + 1, 36) + '}'));
    end;
  end else
    result.Event := AObjectManager.Find<TPubEvent>(DirtyStringToGuid( LValue.AsType<String>));

If the entities are being sent over XData, why they are not being deserialized automatically by XData?

The JSON data is within a complex structure.
I'm looking for the best way to transfer data/objects (also within other structures). Of course I can do it individually/manually, since the structure is known, but a central, global serialize/deserialize function would be more convenient.

Well, you an implement your own solver - that's exactly what it is for, for users to provide custom code that solves the references.

But you can make the existing solver public, recompile the packages and see if it solves your issue. If it does, we can make it public in a next version. But first please confirm if it helps for you.

I'll weigh the different options. I need the conversions now and then. I'll report back once I've sufficiently tested the resolver publishing.

1 Like