使用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
相关产品推荐
相关产品推荐

