2010-10-23 16 views
2

J'ai besoin de marshaling personnalisé/unmarchal un TDictionary dans Delphi (XE). Le dictionnaire est déclaré:Custom marshaling TDictionary dans Delphi

TMyRecord = record 
    key11: integer; 
    key12: string; 
    ... 
end; 

TMyDict: TDictionary<string, TMyRecord>; 

Maintenant, si je maréchal le dictionnaire sans l'enregistrement d'un convertisseur de mesure, le placier va mettre toutes sortes de champs dans la chaîne JSON - FOnValueNotify, FKeyCollection, FItems, etc.

Ce que je besoin est une sorte de tableau associatif de tableaux associatifs, à savoir

{"key1":{"key11":"val1","key12":"val2"},"key2":{"key11":"val3","key12":"val4"}} 

Malheureusement, je ne sais pas comment écrire le convertisseur de mesure et reverter. J'utilise Delphi XE et le TJSONMarshal intégré et TJSONUnMarshal.

Remarque: L'utilisation de TDictionary pour cette tâche n'est pas requise. Je ne peux pas venir avec quelque chose de mieux.

+1

Je ne vraiment voir quel est le problème. Est-ce que vous ne pouvez pas extraire les données du dictionnaire? Vous ne pouvez pas générer la chaîne JSON? –

+0

Obtenir les données du dictionnaire n'est pas un problème. Je ne peux pas comprendre comment écrire les fonctions du convertisseur et du convertisseur pour obtenir le résultat désiré. – ciscocert

Répondre

4

Pour un cas simple comme le vôtre, j'ai tendance à utiliser une méthode personnalisée pour représenter mon objet dans JSON. Mais, si vous voulez créer reverter et convertisseur, vous devriez lire cet article: http://www.danieleteti.it/?p=146

4

Une autre option est TSuperObject qui a la capacité de maréchal à/de JSON en utilisant RTTI:

type 
    TData = record 
    str: string; 
    int: Integer; 
    bool: Boolean; 
    flt: Double; 
    end; 
var 
    ctx: TSuperRttiContext; 
    data: TData; 
    obj: ISuperObject; 
begin 
    ctx := TSuperRttiContext.Create; 
    try 
    data := ctx.AsType<TData>(SO('{str: "foo", int: 123, bool: true, flt: 1.23}')); 
    obj := ctx.AsJson<TData>(data); 
    finally 
    ctx.Free; 
    end; 
end;