Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# JSON序列化-如何使用JSON.net/Newtonsoft展平嵌套对象结构_C#_Json_Serialization_Json.net - Fatal编程技术网

C# JSON序列化-如何使用JSON.net/Newtonsoft展平嵌套对象结构

C# JSON序列化-如何使用JSON.net/Newtonsoft展平嵌套对象结构,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我有以下JSON结构: { "Name":"", "Children":[ { "ID":"1", "MetaData":[ { "Info":{ "GUID":"cdee360d-7ea9-477d-994f-12f492b9e1ed" },

我有以下JSON结构:

{
       "Name":"",
       "Children":[
          {
             "ID":"1",
             "MetaData":[
                {
                   "Info":{
                      "GUID":"cdee360d-7ea9-477d-994f-12f492b9e1ed"
                   },
                   "Data":{
                      "Text":"8"
                   },
                   "Name":"DataId"
                }
             ]
          }
       ]
    }
我想展平数组中的元数据、嵌套信息和数据对象。我还想使用Name字段作为文本值的字段名,使其成为“DataId”:“8”

到目前为止,我已经使用了一个合同解析程序:

private class DynamicContractResolver : DefaultContractResolver
        {
            private readonly List<string> _propertiesToSerialize;
            private readonly List<string> _itemTypeNames;

            public DynamicContractResolver(List<string> propertiesToSerialize, List<string> itemTypeNames)
            {
                _propertiesToSerialize = propertiesToSerialize;

                _itemTypeNames = itemTypeNames;
            }

            protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
            {
                var properties = base.CreateProperties(type, memberSerialization);

                    properties = properties.Where(p => _propertiesToSerialize.Contains(p.PropertyName)).ToList();
                }

                return properties;
            }
}
私有类DynamicContractResolver:DefaultContractResolver
{
私有只读列表_propertiesToSerialize;
私有只读列表_itemTypeNames;
公共DynamicContractResolver(列表属性序列化,列表项类型名称)
{
_propertiesToSerialize=propertiesToSerialize;
_itemTypeNames=itemTypeNames;
}
受保护的重写IList CreateProperties(类型类型,MemberSerialization MemberSerialization)
{
var properties=base.CreateProperties(类型、成员序列化);
properties=properties.Where(p=>_propertiesToSerialize.Contains(p.PropertyName)).ToList();
}
归还财产;
}
}

如何获得所需的序列化?

如果您根本不想修改类型,可以使用加载和预处理JSON,如下所示:

        // Load the JSON into an intermediate JObject
        var rootObj = JObject.Parse(json);

        // Restructure the JObject hierarchy
        foreach (var obj in rootObj.SelectTokens("Children[*]").OfType<JObject>())
        {
            var metadata = obj.SelectToken("MetaData[0]"); // Get the first entry in the "MetaData" array.
            if (metadata != null)
            {
                // Remove the entire "Metadata" property.
                metadata.Parent.RemoveFromLowestPossibleParent();
                // Set the name and value
                var name = metadata.SelectToken("Name");
                var id = metadata.SelectToken("Data.Text");
                if (name != null && id != null)
                    obj[(string)name] = (string)id;
                // Move all other atomic values.
                foreach (var value in metadata.SelectTokens("..*").OfType<JValue>().Where(v => v != id && v != name).ToList())
                    value.MoveTo(obj);
            }
        }
        Debug.WriteLine(rootObj);

        // Now deserialize the preprocessed JObject to the final class
        var root = rootObj.ToObject<RootObject>();
//将JSON加载到中间作业对象中
var rootObj=JObject.Parse(json);
//重新构造JObject层次结构
foreach(rootObj.SelectTokens(“Children[*]”)of type()中的var obj)
{
var metadata=obj.SelectToken(“元数据[0]”;//获取“元数据”数组中的第一个条目。
if(元数据!=null)
{
//删除整个“元数据”属性。
metadata.Parent.RemoveFromLowestPossibleParent();
//设置名称和值
变量名称=元数据。选择标记(“名称”);
var id=metadata.SelectToken(“Data.Text”);
if(name!=null&&id!=null)
obj[(字符串)名称]=(字符串)id;
//移动所有其他原子值。
foreach(metadata.SelectTokens(“…*”)of type().Where(v=>v!=id&&v!=name).ToList()中的变量值)
值。移动到(obj);
}
}
Debug.WriteLine(rootObj);
//现在将预处理的JObject反序列化到最后一个类
var root=rootObj.ToObject();
为方便起见,使用两种简单的扩展方法:

public static class JsonExtensions
{
    public static void RemoveFromLowestPossibleParent(this JToken node)
    {
        if (node == null)
            throw new ArgumentNullException();
        var contained = node.AncestorsAndSelf().Where(t => t.Parent is JArray || t.Parent is JObject).FirstOrDefault();
        if (contained != null)
            contained.Remove();
    }

    public static void MoveTo(this JToken token, JObject newParent)
    {
        if (newParent == null)
            throw new ArgumentNullException();
        var toMove = token.AncestorsAndSelf().OfType<JProperty>().First(); // Throws an exception if no parent property found.
        toMove.Remove();
        newParent.Add(toMove);
    }
}
公共静态类JsonExtensions
{
公共静态void RemoveFromLowestPossibleParent(此JToken节点)
{
if(node==null)
抛出新ArgumentNullException();
var contained=node.AncestorsAndSelf()。其中(t=>t.Parent是JArray | | t.Parent是JObject)。FirstOrDefault();
如果(包含!=null)
包含。删除();
}
公共静态void MoveTo(此JToken令牌,JObject newParent)
{
if(newParent==null)
抛出新ArgumentNullException();
var toMove=token.AncestorsAndSelf().OfType().First();//如果未找到父属性,则引发异常。
toMove.Remove();
newParent.Add(toMove);
}
}

如果您根本不想修改类型,可以使用加载和预处理JSON,如下所示:

        // Load the JSON into an intermediate JObject
        var rootObj = JObject.Parse(json);

        // Restructure the JObject hierarchy
        foreach (var obj in rootObj.SelectTokens("Children[*]").OfType<JObject>())
        {
            var metadata = obj.SelectToken("MetaData[0]"); // Get the first entry in the "MetaData" array.
            if (metadata != null)
            {
                // Remove the entire "Metadata" property.
                metadata.Parent.RemoveFromLowestPossibleParent();
                // Set the name and value
                var name = metadata.SelectToken("Name");
                var id = metadata.SelectToken("Data.Text");
                if (name != null && id != null)
                    obj[(string)name] = (string)id;
                // Move all other atomic values.
                foreach (var value in metadata.SelectTokens("..*").OfType<JValue>().Where(v => v != id && v != name).ToList())
                    value.MoveTo(obj);
            }
        }
        Debug.WriteLine(rootObj);

        // Now deserialize the preprocessed JObject to the final class
        var root = rootObj.ToObject<RootObject>();
//将JSON加载到中间作业对象中
var rootObj=JObject.Parse(json);
//重新构造JObject层次结构
foreach(rootObj.SelectTokens(“Children[*]”)of type()中的var obj)
{
var metadata=obj.SelectToken(“元数据[0]”;//获取“元数据”数组中的第一个条目。
if(元数据!=null)
{
//删除整个“元数据”属性。
metadata.Parent.RemoveFromLowestPossibleParent();
//设置名称和值
变量名称=元数据。选择标记(“名称”);
var id=metadata.SelectToken(“Data.Text”);
if(name!=null&&id!=null)
obj[(字符串)名称]=(字符串)id;
//移动所有其他原子值。
foreach(metadata.SelectTokens(“…*”)of type().Where(v=>v!=id&&v!=name).ToList()中的变量值)
值。移动到(obj);
}
}
Debug.WriteLine(rootObj);
//现在将预处理的JObject反序列化到最后一个类
var root=rootObj.ToObject();
为方便起见,使用两种简单的扩展方法:

public static class JsonExtensions
{
    public static void RemoveFromLowestPossibleParent(this JToken node)
    {
        if (node == null)
            throw new ArgumentNullException();
        var contained = node.AncestorsAndSelf().Where(t => t.Parent is JArray || t.Parent is JObject).FirstOrDefault();
        if (contained != null)
            contained.Remove();
    }

    public static void MoveTo(this JToken token, JObject newParent)
    {
        if (newParent == null)
            throw new ArgumentNullException();
        var toMove = token.AncestorsAndSelf().OfType<JProperty>().First(); // Throws an exception if no parent property found.
        toMove.Remove();
        newParent.Add(toMove);
    }
}
公共静态类JsonExtensions
{
公共静态void RemoveFromLowestPossibleParent(此JToken节点)
{
if(node==null)
抛出新ArgumentNullException();
var contained=node.AncestorsAndSelf()。其中(t=>t.Parent是JArray | | t.Parent是JObject)。FirstOrDefault();
如果(包含!=null)
包含。删除();
}
公共静态void MoveTo(此JToken令牌,JObject newParent)
{
if(newParent==null)
抛出新ArgumentNullException();
var toMove=token.AncestorsAndSelf().OfType().First();//如果未找到父属性,则引发异常。
toMove.Remove();
newParent.Add(toMove);
}
}

能否显示正在序列化的C#类?另外,
元数据
数组总是保证只有一个元素吗?在不发布所有代码的情况下,这些类基本上是一个树结构,与第一个示例JSON的结构相同。元数据可以有许多元素。我已经找到了一个可以接受的解决方案,为一些嵌套结构创建别名类型属性以将其展平。我本不想让底层类参与其中,但至少它只是额外的属性,几乎没有逻辑。你能展示一下你正在序列化的C#类吗?
元数据
数组也总是有保证的吗