You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Delphi TDictionary序列化为符合C#要求的JSON字符串?

Delphi中序列化TDictionary为指定JSON格式的解决方案

你通过REST.JsonReflect自定义拦截器的方向是正确的,但现有代码存在细节问题,导致序列化结构不符合预期。以下是修正后的实现方案,同时提供其他替代方法:

方法一:修正自定义JSON拦截器

原代码的核心问题是没有正确告诉序列化器直接输出转换后的JSON值,而是将其当作普通对象处理。调整拦截器实现和属性参数即可解决:

uses System.Rtti, Rest.Json, System.Generics.Collections, Rest.JsonReflect,
  System.JSON;

type
  TDictionaryInterceptor = class(TJSONInterceptor)
  public
    function ObjectConverter(Data: TObject; Field: string): TObject; override;
    procedure ObjectsConverter(Data: TObject; Field: string; out AObjects: TArray<TObject>); override;
  end;

function TDictionaryInterceptor.ObjectConverter(Data: TObject; Field: string): TObject;
var
  Dict: TDictionary<string, string>;
  JsonObj: TJSONObject;
  KVPair: TPair<string, string>;
begin
  // 直接将目标对象转为TDictionary类型
  Dict := TDictionary<string, string>(Data);
  JsonObj := TJSONObject.Create;
  try
    for KVPair in Dict do
      JsonObj.AddPair(KVPair.Key, KVPair.Value);
    Result := JsonObj;
  except
    JsonObj.Free;
    raise;
  end;
end;

procedure TDictionaryInterceptor.ObjectsConverter(Data: TObject; Field: string; out AObjects: TArray<TObject>);
begin
  // 空实现,阻止序列化器遍历字典内部成员
  AObjects := [];
end;

DictionaryReflectAttribute = class(JsonReflectAttribute)
public
  constructor Create;
end;

constructor DictionaryReflectAttribute.Create;
begin
  // 关键参数:指定处理JSON值而非普通对象
  inherited Create(ctJSONValue, rtJSONValue, TDictionaryInterceptor);
end;

TExample = class
public
  [DictionaryReflectAttribute]
  dictionary: TDictionary<string, string>;
end;

测试代码

var
  Example: TExample;
  JsonStr: string;
begin
  Example := TExample.Create;
  try
    Example.dictionary := TDictionary<string, string>.Create;
    Example.dictionary.Add('key1', 'KeyValue1');
    Example.dictionary.Add('key2', 'KeyValue2');
    JsonStr := TJson.ObjectToJsonString(Example);
    // 输出结果:{"dictionary":{"key1":"KeyValue1","key2":"KeyValue2"}}
  finally
    Example.dictionary.Free;
    Example.Free;
  end;
end;

方法二:手动构建TJSONObject(无需模型类)

如果场景简单,可跳过模型类直接构建JSON结构,避免拦截器的复杂度:

var
  RootObj: TJSONObject;
  DictObj: TJSONObject;
  Dict: TDictionary<string, string>;
  KVPair: TPair<string, string>;
  JsonStr: string;
begin
  Dict := TDictionary<string, string>.Create;
  try
    Dict.Add('key1', 'KeyValue1');
    Dict.Add('key2', 'KeyValue2');

    DictObj := TJSONObject.Create;
    try
      for KVPair in Dict do
        DictObj.AddPair(KVPair.Key, KVPair.Value);

      RootObj := TJSONObject.Create;
      try
        RootObj.AddPair('dictionary', DictObj);
        JsonStr := RootObj.ToString;
      finally
        RootObj.Free;
      end;
    finally
      Dict.Free;
    end;
end;

方法三:使用第三方JSON库

原生REST.Json对复杂集合的支持有限,可选择第三方库简化开发,比如SuperObject或mORMot的JSON模块:

以SuperObject为例:

uses SuperObject;

var
  Dict: TDictionary<string, string>;
  JsonObj: ISuperObject;
  KVPair: TPair<string, string>;
  JsonStr: string;
begin
  Dict := TDictionary<string, string>.Create;
  try
    Dict.Add('key1', 'KeyValue1');
    Dict.Add('key2', 'KeyValue2');

    JsonObj := SO;
    JsonObj.S['dictionary'] := SO;
    for KVPair in Dict do
      JsonObj.O['dictionary'].S[KVPair.Key] := KVPair.Value;

    JsonStr := JsonObj.AsString;
  finally
    Dict.Free;
  end;
end;

内容的提问来源于stack exchange,提问作者stmpakir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:17:56