JSON:将 DataRow 序列化为父对象

     2023-02-24     254

关键词:

【中文标题】JSON:将 DataRow 序列化为父对象【英文标题】:JSON: Serializing DataRow into parent object 【发布时间】:2020-06-03 15:25:37 【问题描述】:

我有一个树形结构,由 DataTable 中的行创建,每个 DataRow 生成一个节点。

每个节点当然应该包含子节点,还要包含源DataRow:

    public class TreeNode
    
        public List<TreeNode> Items  get; internal set; 
        public JToken RowJToken  get; internal set; 
    

(RowJToken而不是DataRow的原因见文末代码)

当我序列化树结构时,我需要以这种方式序列化每个 TreeNode(这由消费客户端决定):


  "items": [children],
  "columnA": "ValueA",
  "columnB": "ValueB",
  "columnC": "ValueC"

其中“[children]”表示节点的子节点(为简洁起见省略)。

然而,结果却是:


  "items": [children],
  "rowJToken": 
    "columnA": "ValueA",
    "columnB": "ValueB",
    "columnC": "ValueC"
  

问题:如何将 RowJToken 内容与 Items 数组“在同一级别”序列化,即不嵌入到“rowJToken”对象中?

事先不知道 DataTable 中的列集(但我知道列名不会与“项目”冲突)。

下面的代码片段。请注意,在这种情况下,树结构本身的构造不应该很重要。 我在 TreeNode 中存储 RowJToken 而不是 DataRow 的原因是 JSON.Net 没有 DataRow 序列化程序,而只有一个 DataTable 序列化程序。因此,我先将DataTable序列化为一个JArray,然后将DataRow对应的JToken,粘贴到TreeNode中。

    public class TreeNode
    
        public JToken RowJToken  get; internal set; 
        public List<TreeNode> Items  get; internal set; 
    

...

        List<TreeNode> treeNodes = GetTreeNodes(dataTable, childColumnName, parentColumnName);

        DefaultContractResolver contractResolver = new DefaultContractResolver
        
            NamingStrategy = new CamelCaseNamingStrategy()
        ;

        string json = JsonConvert.SerializeObject(treeNodes, new JsonSerializerSettings
        
            ContractResolver = contractResolver,
            Formatting = Formatting.Indented
        );

...

        private List<TreeNode> GetTreeNodes(DataTable dataTable, string childColumnName, string parentColumnName)
        
            DataColumn childColumn = dataTable.Columns[childColumnName];
            DataColumn parentColumn = dataTable.Columns[parentColumnName];

            //  
            //  Use the serializer for DataTable to generate a JSON array, containing each DataRow
            //  
            var jArray = JArray.FromObject(dataTable, JsonSerializer.CreateDefault(new JsonSerializerSettings  NullValueHandling = NullValueHandling.Ignore ));

            //  
            //  The use of "NullObject" is merely to allow NULL values as the key to the dictionary
            //  
            Dictionary<NullObject<string>, List<TreeNode>> hash = new Dictionary<NullObject<string>, List<TreeNode>>();

            var rowIndex = 0;

            foreach (DataRow r in dataTable.Rows)
            
                string childId = r.Field<string>(childColumn);
                string parentId = r.Field<string>(parentColumn);

                if (!hash.TryGetValue(childId, out List<TreeNode> childIdTreeNodes))
                
                    childIdTreeNodes = new List<TreeNode>();
                    hash.Add(childId, childIdTreeNodes);
                

                if (!hash.TryGetValue(parentId, out List<TreeNode> parentIdTreeNodes))
                
                    parentIdTreeNodes = new List<TreeNode>();
                    hash.Add(parentId, parentIdTreeNodes);
                

                //  
                //  Put the JToken which corresponds to this DataRow in the TreeNode
                //  
                var rowJToken = jArray[rowIndex++];
                parentIdTreeNodes.Add(new TreeNode()
                
                    Items = childIdTreeNodes,
                    RowJToken = rowJToken
                );
            

            //  
            //  Return the root node(s), i.e. the nodes with NULL as parent ID
            //  
            return hash[null];
        

【问题讨论】:

【参考方案1】:

你可以通过一些简单的改变得到你想要的输出。

    在您的TreeNode 类中,将RowJToken 的类型从JToken 更改为JObject。 (您可能还想将属性名称更改为 RowJObject,以保持一致,但这不是绝对必要的。)

    public JObject RowJToken  get; internal set; 
    

    [JsonExtensionData] 属性装饰RowJToken 属性。

    [JsonExtensionData]
    public JObject RowJToken  get; internal set; 
    

    在您的GetTreeNodes 方法中,将从jArray 检索到的JToken 转换为JObject

    var rowJToken = (JObject)jArray[rowIndex++];
    

就是这样。当您序列化treeNodes 列表时,每个TreeNodeRowJToken 属性将与其各自的Items 数组处于同一级别。

概念证明:https://dotnetfiddle.net/LEaeXo

【讨论】:

太好了,谢谢,效果很好!我真的很接近,使用 JsonExtensionData 属性和所有属性,但是使用 JToken 我得到了一个错误。 没问题;很高兴我能帮上忙! [JsonExtensionData] 不适用于JToken,因为JToken 没有实现IDictionary&lt;string, JToken&gt;。但是JObject 可以。事实证明,您的 JArray 中已经有 JObjects,因此只需更改类型并执行转换即可。

将单个 KeyValuePair<> 序列化为 JSON 作为父对象的一部分

】将单个KeyValuePair<>序列化为JSON作为父对象的一部分【英文标题】:SerializesingleKeyValuePair<>toJSONaspartofaparentobject【发布时间】:2020-08-3101:58:44【问题描述】:我有一个这样的DTO类:publicclassMyDtopublicKeyValuePair<string,string&... 查看详情

轻松将对象序列化为 JSON

】轻松将对象序列化为JSON【英文标题】:EasilyserializeanobjecttoJSON【发布时间】:2015-01-1913:31:12【问题描述】:如何将Swift对象序列化为JSON,例如以下对象:classOrdervarid:Intvartitle:Stringvaremail:Stringinit(id:Int,title:String,email:String)self.id=i... 查看详情

将 JSON 反序列化为匿名对象

】将JSON反序列化为匿名对象【英文标题】:DeserializeJSONtoanonymousobject【发布时间】:2011-10-1719:16:55【问题描述】:在C#中,我已经通过使用这样的代码成功地将匿名对象序列化为JSON...varobj=newAmount=108,Message="Hello";JavaScriptSerializerser... 查看详情

将对象序列化为 JSON

】将对象序列化为JSON【英文标题】:SerializinganobjecttoJSON【发布时间】:2010-10-0804:40:50【问题描述】:如何在JavaScript中?【问题讨论】:【参考方案1】:您正在寻找JSON.stringify()。【讨论】:将JSON.stringify()与包含数组的javascript... 查看详情

将 JSON 反序列化为对象

】将JSON反序列化为对象【英文标题】:DeserializingJSONintoanobject【发布时间】:2016-03-1707:26:47【问题描述】:我有一些JSON:"foo":["bar":"baz","bar":"qux"]我想将其反序列化为一个集合。我已经定义了这个类:publicclassFoopublicstringbarget;set;... 查看详情

将 JSON 反序列化为对象

】将JSON反序列化为对象【英文标题】:DeserializingJSONintoanobject【发布时间】:2021-12-1621:52:42【问题描述】:我有一些JSON:"foo":["bar":"baz","bar":"qux"]我想将其反序列化为一个集合。我已经定义了这个类:publicclassFoopublicstringbarget;set;... 查看详情

如何将属性序列化为 json 对象?

】如何将属性序列化为json对象?【英文标题】:HowcanIserializepropertiesasjsonobject?【发布时间】:2019-03-2108:44:49【问题描述】:如何使用jackson序列化以下通用响应?publicclassGenericResponseprivateStringresource;privateIntegerstatus;privateErrorInfores... 查看详情

将实体框架对象序列化为 JSON

】将实体框架对象序列化为JSON【英文标题】:SerializingEntityFrameworkObjectsintoJSON【发布时间】:2011-12-0902:32:27【问题描述】:publicclassGenericHandler:IHttpHandlerpublicclassASSystempublicstringSIDget;set;publicstringDescriptionget;set;publicstringS 查看详情

将表单序列化为json对象

$.fn.serializeJson=function(){  varserializeObj={};  vararray=this.serializeArray();  varstr=this.serialize();  $(array).each(function(){    if(serializeObj[this.name]){      if($.isArray(serializeObj 查看详情

将 PHP 对象序列化为 JSON

】将PHP对象序列化为JSON【英文标题】:SerializingPHPobjecttoJSON【发布时间】:2011-10-1318:37:07【问题描述】:所以当我偶然发现新的JsonSerializableInterface时,我在php.net中寻找有关将PHP对象序列化为JSON的信息。不过它只是PHP>=5.4,而... 查看详情

如何将表行序列化为 json 对象

】如何将表行序列化为json对象【英文标题】:Howtoserializetablerowtojsonobject【发布时间】:2017-03-0713:41:34【问题描述】:如何将表格序列化为json数组,使每个数组元素都包含代表一个表格行的json对象:[name:"variable1",valuetostore:"a-b",t... 查看详情

使用 Json.net 将 JSON 对象反序列化为动态对象

】使用Json.net将JSON对象反序列化为动态对象【英文标题】:DeserializeJSONobjectintodynamicobjectusingJson.net【发布时间】:2011-05-3023:13:12【问题描述】:是否可以使用json.net从json反序列化返回动态对象?我想做这样的事情:dynamicjsonRespons... 查看详情

将 PHP 对象图序列化/反序列化为 JSON

】将PHP对象图序列化/反序列化为JSON【英文标题】:Serialize/unserializePHPobject-graphtoJSON【发布时间】:2012-05-1610:06:15【问题描述】:我想将完整的PHP对象图序列化为JSON字符串表示,然后将其反序列化回相同的PHP对象图。以下是我考... 查看详情

将 JSON 反序列化为现有对象 (Java)

】将JSON反序列化为现有对象(Java)【英文标题】:DeserializeJSONintoexistingobject(Java)【发布时间】:2012-09-1304:09:20【问题描述】:我想知道如何让JacksonJSON库将JSON反序列化为现有对象?我试图找到如何做到这一点;但它似乎只能接受... 查看详情

将 JSON 命名属性反序列化为 .Net 对象

】将JSON命名属性反序列化为.Net对象【英文标题】:DeserializeJSONnamedpropertyto.NetObject【发布时间】:2012-03-0109:56:21【问题描述】:我使用的API提供了JSON负载。响应的一部分有一个包含命名对象数组的属性。我想我想将这部分反序... 查看详情

将 ES6 类对象序列化为 JSON

】将ES6类对象序列化为JSON【英文标题】:SerializinganES6classobjectasJSON【发布时间】:2017-03-0505:41:52【问题描述】:classMyClassconstructor()this.foo=3varmyClass=newMyClass()我想将myClass对象序列化为json。我能想到的一种简单方法是,因为每个... 查看详情

PRAW:将评论和提交对象序列化为 JSON

】PRAW:将评论和提交对象序列化为JSON【英文标题】:PRAW:serializingCommentandSubmissionobjectsasJSON【发布时间】:2014-09-0502:15:03【问题描述】:我目前正在开发一个使用praw进行数据挖掘的reddit爬虫。我想从subreddits爬取cmets和提交,然... 查看详情

javaserialization可以将对象反序列化为父类的实例(代码片段)

...基类的类。classAnotherextendsBase...//somefields我有一个Another的序列化实例。我可以将它反序列化为Base的例子吗?答案是的,一般情况下你可以这样做。最简单的示例忽略流初始化,关闭,异常等。cla 查看详情