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

使用DataContractJsonSerializer序列化字典时移除根元素

问题:移除DataContractJsonSerializer序列化字典时的根元素"dictionary"

我有一个Dictionary<string, string>需要序列化为JSON,字典定义如下:

xrmParentPluginContextProperties = new Dictionary<string, string> {
       { "source", className },
       { "correlationId", executionContext.ParentContext.CorrelationId.ToString() },
       { "depth", executionContext.ParentContext.Depth.ToString() },
       { "initiatingUserId", executionContext.ParentContext.InitiatingUserId.ToString() },
       { "isInTransaction", executionContext.ParentContext.IsInTransaction.ToString() },
       { "isolationMode", executionContext.ParentContext.IsolationMode.ToString() },
       { "message", executionContext.ParentContext.MessageName },
       { "mode", getModeName(executionContext.ParentContext.Mode) },
       { "operationId", executionContext.ParentContext.OperationId.ToString() },
       { "orgId", executionContext.ParentContext.OrganizationId.ToString() },
       { "orgName", executionContext.ParentContext.OrganizationName },
       { "requestId", executionContext.ParentContext.RequestId.ToString() },
       { "userId", executionContext.ParentContext.UserId.ToString() },
       { "entityId", executionContext.ParentContext.PrimaryEntityId.ToString() },
       { "entityName", executionContext.ParentContext.PrimaryEntityName },
       { "type", "Plugin" },
       { "stage", getStageName(executionContext.Stage) }
};

我用一个辅助类包装该字典进行序列化:

public class DictionarySerializationHelperClass
{
    public Dictionary<string, string> dictionary;

    public DictionarySerializationHelperClass()
    {
    }

    public DictionarySerializationHelperClass(Dictionary<string, string> dict)
    {
        this.dictionary = dict;
    }
}

序列化调用代码:

DictionarySerializationHelperClass dictionaryClass = new DictionarySerializationHelperClass(XrmProperties.currentPluginContext);
return SerializationHelper.JsonSerialize(dictionaryClass);

序列化实现:

public static string JsonSerialize<T>(T objectToSerialize) where T : class, new()
{
    string serialisedJson = null;
    DataContractJsonSerializer serializer;
    try
    {
        using (MemoryStream serializationStream = new MemoryStream())
        {
            if (typeof(T) == typeof(Dictionary<string, string>))
            {
                serializer = new DataContractJsonSerializer(typeof(T), new DataContractJsonSerializerSettings()
                {
                    UseSimpleDictionaryFormat = true,
                    RootName = string.Empty
                });
            }
            else
            {
                serializer = new DataContractJsonSerializer(typeof(T));
            }
            
            serializer.WriteObject(serializationStream, objectToSerialize);
            serializationStream.Position = 0;
            var reader = new StreamReader(serializationStream);
            serialisedJson = reader.ReadToEnd();
        }
    }
    catch (Exception ex)
    {
        string error = $"Error on Serializing JSON: \r\n\r\n{objectToSerialize}";

        throw new JsonException(error, ex);
    }
    return serialisedJson;
}

当前序列化结果会包含根元素"dictionary":

{
   "dictionary":{
      "source":"asdasdasd",
      "correlationId":"asdasdasd",
      "depth":"1",
      "initiatingUserId":"asdasdasd",
      "isInTransaction":"False",
      "isolationMode":"2",
      "message":"Retrieve",
      "mode":"Synchronus",
      "operationId":"asdasd",
      "orgId":"esdfsdf",
      "orgName":"asdasdasd",
      "requestId":"asdasdasd",
      "userId":"asdasdasd",
      "entityId":"asdasdasd",
      "entityName":"incident",
      "type":"Plugin",
      "stage":"Pre-operation"
   }
}

我希望移除根元素,得到如下结构:

{
  "source":"asdasdasd",
  "correlationId":"asdasdasd",
  "depth":"1",
  "initiatingUserId":"asdasdasd",
  "isInTransaction":"False",
  "isolationMode":"2",
  "message":"Retrieve",
  "mode":"Synchronus",
  "operationId":"asdasd",
  "orgId":"esdfsdf",
  "orgName":"asdasdasd",
  "requestId":"asdasdasd",
  "userId":"asdasdasd",
  "entityId":"asdasdasd",
  "entityName":"incident",
  "type":"Plugin",
  "stage":"Pre-operation"
}

尝试设置RootName为空没有效果,求解决思路。


解决思路

方案一:直接序列化字典,废弃包装类

你的序列化方法已经支持直接处理Dictionary<string, string>并启用简单格式,不需要额外包装类。修改调用代码,直接传入字典即可:

return SerializationHelper.JsonSerialize(XrmProperties.currentPluginContext);

这样会触发方法中typeof(T) == typeof(Dictionary<string, string>)的分支,直接输出无嵌套的JSON结构。

方案二:修改包装类为字典的子类

如果必须保留包装类(比如有扩展需求),可以让包装类继承Dictionary<string, string>,这样序列化时会被当作字典处理:

public class DictionarySerializationHelperClass : Dictionary<string, string>
{
    public DictionarySerializationHelperClass() {}
    public DictionarySerializationHelperClass(Dictionary<string, string> dict) : base(dict) {}
}

调用代码无需修改,序列化时会自动使用简单字典格式,不会生成根元素。

方案三:调整序列化方法逻辑,适配包装类

如果不想修改调用代码和包装类结构,可以在序列化方法中判断传入的是包装类时,直接序列化内部的字典对象:

public static string JsonSerialize<T>(T objectToSerialize) where T : class, new()
{
    string serialisedJson = null;
    DataContractJsonSerializer serializer;
    try
    {
        using (MemoryStream serializationStream = new MemoryStream())
        {
            Type targetType = typeof(T);
            object targetObject = objectToSerialize;
            
            // 处理包装类,直接序列化内部字典
            if (typeof(DictionarySerializationHelperClass).IsAssignableFrom(targetType))
            {
                var helper = objectToSerialize as DictionarySerializationHelperClass;
                targetType = typeof(Dictionary<string, string>);
                targetObject = helper.dictionary;
                serializer = new DataContractJsonSerializer(targetType, new DataContractJsonSerializerSettings()
                {
                    UseSimpleDictionaryFormat = true,
                    RootName = string.Empty
                });
            }
            else if (targetType == typeof(Dictionary<string, string>))
            {
                serializer = new DataContractJsonSerializer(targetType, new DataContractJsonSerializerSettings()
                {
                    UseSimpleDictionaryFormat = true,
                    RootName = string.Empty
                });
            }
            else
            {
                serializer = new DataContractJsonSerializer(targetType);
            }
            
            serializer.WriteObject(serializationStream, targetObject);
            serializationStream.Position = 0;
            var reader = new StreamReader(serializationStream);
            serialisedJson = reader.ReadToEnd();
        }
    }
    catch (Exception ex)
    {
        string error = $"Error on Serializing JSON: \r\n\r\n{objectToSerialize}";
        throw new JsonException(error, ex);
    }
    return serialisedJson;
}

这样传入包装类时,方法会自动提取内部字典进行序列化,得到期望的无嵌套结构。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:56:08