2
votes

I have a class in Delphi which I export in jsonmarshalled file.

I am skipping some Fields using the JSONMarshalledAttribute, which resides in the unit: REST.JSON.Types. More literature here

[JSONMarshalledAttribute(False)]                                                                                                                                        
Field1: double;                                                                                                                                                         
[JSONMarshalledAttribute(False)]                                                                                                                                        
Field2: double;                                                                                                                                                         

So far this works great.

My question is: Can I change the JSONMarshalledAttribute to True during runtime?

EDIT 1:

As requested here is the code:

Suppose we have a Form2:TForm and within the form as follows...:

Interface(I am skipping the attributes of the form....)

type                                                                                                                                                                    
  TmyClass = class(Tobject)                                                                                                                                             
  private                                                                                                                                                               
    [JSONMarshalledAttribute(false)]                                                                                                                                    
    FName: string;                                                                                                                                                      
    FVal1: double;                                                                                                                                                      
  public                                                                                                                                                                
    property Name: string read FName write FName;                                                                                                                       
    property Val1: double read FVal1 write FVal1;                                                                                                                       
  end;                                                                                                                                                                  

and then in the implementation:

  procedure TForm2.Button2Click(Sender: Tobject);                                                                                                                       
  var                                                                                                                                                                   
    LArray: TJSONArray;                                                                                                                                                 
  begin                                                                                                                                                                 
    MyClass := TmyClass.Create;                                                                                                                                         
    MyClass.name := 'myNAme';                                                                                                                                           

    LArray := myMarshaler(MyClass, 'FName', True);                                                                                                                      
 end;                                                                                                                                                                   

and the actual function that returns a TJSONArray:

  function TForm2.myMarshaler(myclass: TmyClass; Field: string; Marshal: Boolean)                                                                                       
    : TJSONArray;                                                                                                                                                       
  var                                                                                                                                                                   
    Marshaler: TJSONMarshal;                                                                                                                                            
    JSONObject: TJSONObject;                                                                                                                                            
    LArray: TJSONArray;                                                                                                                                                 
  begin                                                                                                                                                                 
    Marshaler := TJSONMarshal.Create(TJSONConverter.Create);                                                                                                            
    try                                                                                                                                                                 
       Marshaler.RegisterJSONMarshalled(myclass, Field,Marshal);                                                                                                        
      // Marshaler.DateFormat := jdfUnix;                                                                                                                               
      JSONObject := Marshaler.Marshal(myclass) as TJSONObject;                                                                                                          
      LArray := TJSONArray.Create;                                                                                                                                      
      LArray.AddElement(JSONObject);                                                                                                                                    
      result := LArray;                                                                                                                                                 
    finally                                                                                                                                                             
      FreeAndNil(Marshaler);                                                                                                                                            
    end;                                                                                                                                                                
  end;                                                                                                                                                                  

That will not work because Marshaler.RegisterJSONMarshalled requires a TClass as an argument type, but I want to input my own custom classes which are derived from TObject.

and this is the error:

[dcc32 Error] Unit2.pas(134): E2250 There is no overloaded version of >'RegisterJSONMarshalled' that can be called with these arguments

How do I fix this?

2

2 Answers

2
votes

You can not change the attribute, but you can overwrite it.

According to the documentation, it should work with:

Marshaler.RegisterJSONMarshalled(TYourClass, 'Field1', true);

Therefore, you can not use the class function TJson.ObjectToJsonObject(...), - you'll have to create the marshaller (from the unit REST.JsonReflect) yourself. Example:

var
  Marshaler: TJSONMarshal;
  JSONObject: TJSOnObject;
begin
  Marshaler := TJSONMarshal.Create(TJSONConverter.Create);
    try
      Marshaler.RegisterJSONMarshalled(TYourClass, 'Field1');
      Marshaler.DateFormat :=jdfUnix;
      JSONObject := Marshaler.Marshal(AObject) as TJSOnObject;    
      Result := JSONObject;
    finally
      FreeAndNil(Marshaler);
    end;
  end;

To remove the overwritten value you can call UnregisterJSONMarshalled.

Update to clarify how to this method is called:

The declared method signature is:

RegisterJSONMarshalled(clazz: TClass; Field: string; Marshal: Boolean);

So there are three parameters to pass in:

Marshaler.RegisterJSONMarshalled(myclass.ClassType, Field, Marshal); 

or even more simpler:

Marshaler.RegisterJSONMarshalled(TMyClass, Field, Marshal); 

You have to pass in the class type of your class.

0
votes

No you cannot change attributes at runtime. You'll have to find a different approach to handle the dynamic nature of your marshaling.