gpt4 book ai didi

c# - 遍历从 JSON 文件生成的动态对象的问题

转载 作者:行者123 更新时间:2023-11-30 23:26:08 27 4
gpt4 key购买 nike

我有一个 json 文件(为了这个问题)我简化了它:

{
"servername": {
"goodvolumes": [
{
"Name": "vol1",
"State": "online",
"Size": "12.0 TB"
},
{
"Name": "vol2",
"State": "online",
"Size": "10.0 TB"
}
],
"BadVolumes": {
"Name": "badVol",
"State": "offline",
"TotalSize": "120GB"
}
}
}

当它被读入我的 C# 时,我有一个 System.Collections.Generic.Dictionary<string,object> 类型的数据对象.

然后我遍历对象并创建一个模型对象,我将把它传递给我的 View 。

这对我来说是个难题。这是我如何遍历 json 的示例。

//top level of my JSON - the serverName
foreach(serverName in jsonData)
{
//record the serverName

//second level of my JSON - the notification name
foreach(notification in serverName.Value)
{
//record the notification name

//3rd Level of my JSON - iterating the entries
foreach(entry in notification.Value)
{
//Iterating all the values in an entry
foreach(entryValue in entry)
{
//record values in each entry
}

}
}
}

我遇到的问题是,如果只有 1 个条目,则遍历第三级时。

根据 JSON 的性质,如果通知类型有多个条目,那么在我的 notifications.Value 中将有另一个集合列表。在这种情况下,我的代码就像一个魅力。

但是,如果通知只有 1 个条目,notification.value实际上包含 KeyValuePair 的列表对于单个条目中的所有值。所以第 3 级迭代不起作用。它实际上是在尝试迭代该点的值。

不幸的是,我正在使用的 json 无法修改,这是我将要接收的格式。

我希望这能准确解释我遇到的问题。我知道问题出在哪里,只是完全不确定如何解决。

最佳答案

首先,您可以考虑切换到 .如果这样做,您可以直接反序列化为 Dictionary<string, Dictionary<string, List<Dictionary<string, string>>>>使用 SingleOrArrayConverter<Dictionary<string, string>>来自 How to handle both a single item and an array for the same property using JSON.net .这也避免了 proprietary date formatJavaScriptSerializer 使用.

使用 JavaScriptSerializer ,您将需要了解它如何反序列化任意 JSON 数据的一些细节。具体来说,它将 JSON 对象反序列化为 IDictionary<string, object>和 JSON 数组作为某种 非字典,非 string IEnumerable .以下扩展方法实现了这些检查:

public static class JavaScriptSerializerObjectExtensions
{
public static bool IsJsonArray(this object obj)
{
if (obj is string || obj.IsJsonObject())
return false;
return obj is IEnumerable;
}

public static IEnumerable<object> AsJsonArray(this object obj)
{
if (obj is string || obj.IsJsonObject())
return null;
return (obj as IEnumerable).Cast<object>();
}

public static bool IsJsonObject(this object obj)
{
return obj is IDictionary<string, object>;
}

public static IDictionary<string, object> AsJsonObject(this object obj)
{
return obj as IDictionary<string, object>;
}

/// <summary>
/// If the incoming object corresponds to a JSON array, return it. Otherwise wrap it in an array.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static IEnumerable<object> ToJsonArray(this object obj)
{
if (obj.IsJsonArray())
return obj.AsJsonArray();
return new[] { obj };
}

public static string JsonPrimitiveToString(this object obj, bool isoDateFormat = true)
{
if (obj == null)
return null; // Or return "null" if you prefer.
else if (obj is string)
return (string)obj;
else if (obj.IsJsonArray() || obj.IsJsonObject())
return new JavaScriptSerializer().Serialize(obj);
else if (isoDateFormat && obj is DateTime)
// Return in ISO 8601 format not idiosyncratic JavaScriptSerializer format
// https://stackoverflow.com/questions/17301229/deserialize-iso-8601-date-time-string-to-c-sharp-datetime
// https://msdn.microsoft.com/en-us/library/az4se3k1.aspx#Roundtrip
return ((DateTime)obj).ToString("o");
else
{
var s = new JavaScriptSerializer().Serialize(obj);
if (s.Length > 1 && s.StartsWith("\"", StringComparison.Ordinal) && s.EndsWith("\"", StringComparison.Ordinal))
s = s.Substring(1, s.Length - 2);
return s;
}
}
}

然后你可以反序列化如下:

var jsonData = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(jsonString);

Dictionary<string, Dictionary<string, List<Dictionary<string, string>>>> finalData;

// I could have just done var finalData = ... here. I declared finalData explicitly to makes its type explicit.
finalData =
jsonData.ToDictionary(
p1 => p1.Key,
p1 => p1.Value
.AsJsonObject()
.ToDictionary(
p2 => p2.Key,
p2 => (p2.Value.ToJsonArray().Select(a => a.AsJsonObject())).Select(o => o.ToDictionary(p3 => p3.Key, p3 => p3.Value.JsonPrimitiveToString())).ToList()
));

现在您已经有了一个完全类型化的字典层次结构,您应该能够继续创建您的最终模型。

关于c# - 遍历从 JSON 文件生成的动态对象的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36988114/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com