【发布时间】:2017-05-18 20:19:30
【问题描述】:
假设在我的 WebAPI 中,我收到了这样的 json:
{
prop1: "sometext",
prop2: 123,
prop3: true,
prop4: [1,2,3,4,5],
prop5: ["text1", "text2", "text3"]
}
为了处理这些数据,我将其转换为:dynamic data = System.Web.Helpers.Json.Decode(json);。在大多数情况下,使用它真的很容易,但我遇到了需要将这些数据重新传递到数据库的情况。大多数转换都非常简单,可以轻松地遍历 DynamicJsonObject 并将信息发送到数据库。
我的大问题是处理像prop4 和prop5 这样的属性。此数组正在转换为 DynamicJsonArray。要将其转换为原始数组,我目前正在使用这个:
Array arr = (Array) data["prop4"];
data["prop4"] = arr.Cast<Int32>().ToArray();
上面的代码工作正常,它成功地将属性值转换为可以发送到数据库的整数数组。但是,当我使用字符串数组时:
Array arr = (Array) data["prop5"];
data["prop5"] = arr.Cast<string>().ToArray();
data["prop5"] 的值没有改变,当我检查它的值时,它仍然指向System.Web.Helpers.DynamicJsonArray 类型。为什么会这样?
另外,我没有在 C# 中处理动态对象的经验,我使用它是因为在我的情况下,我并不总是知道我收到的 JSON 将具有哪些属性。有没有更清洁的方法来进行这种转换?实际上,是否有任何需要使用动态对象来处理 JSON?
编辑:
抱歉,非常不清楚。为了澄清事情,这就是我实际上正在做的事情:
-
我正在使用通用函数调用来自参数
data的任何数据的数据库过程:public static IEnumerable<Dictionary<string, object>> CallDBProcedure(string proc, dynamic data) { using (NpgsqlConnection conn = new NpgsqlConnection(ConnStr)) { try { conn.Open(); using (var cmd = conn.CreateCommand()) { cmd.CommandText = proc; cmd.CommandType = System.Data.CommandType.StoredProcedure; foreach (string property in data.GetDynamicMemberNames()) { object propertyValue = data[property]; // The method convertNullValue returns the own value if it's not null // and returns DBNull.Value if it's null. Every value must be properly // converted, but I can't directly convert a DynamicJsonArray. cmd.Parameters.Add(new NpgsqlParameter(property, convertNullValue(propertyValue))); } var reader = cmd.ExecuteReader(); return new DrToDictionary().Serialize(reader); } } catch (Exception e) { throw e; } finally { conn.Close(); } } } -
然后,为了避免异常,我在处理
data之前 我将它传递给CallDBProcedure,遍历 DynamicJsonObject 并将其中的每个 DynamicJsonArray 转换为原始数组:public static void ProcessData(dynamic data) { // Directly using data.GetDynamicMemberNames() and modifiying data // inside the loop causes an exception. Using a string list instead (hacky code?). List<string> properties = ((Dictionary<string, object>.KeyCollection) data.GetDynamicMemberNames()).ToList(); foreach (string property in properties) { object propertyValue = data[property]; if (propertyValue != null && propertyValue.GetType() == typeof(DynamicJsonArray)) { Array arr = (Array)data[property]; if (arr.Length == 0) { // This works. data[property] = null; } else { // Discover the type of my array. if (arr.GetValue(0) is int) { // This works. data[property] = arr.Cast<Int32>().ToArray(); } else { // This doesn't. data[property] = arr.Cast<string>().ToArray(); } } } } }
现在我正在迭代data 两次。我知道必须有一种明显而简单的方法来让这个丑陋的代码更干净,但我只是没有看到它。
EDIT2:
我发现的一个解决方案是仅将字符串数组放入不同的变量中。然后我就可以正常使用它们了。我真的不明白为什么动态对象在某些情况下可以更改其类型,而在其他情况下却不能。
EDIT3:
忘了说我收到了这样的 json:dynamic data = System.Web.Helpers.Json.Decode(json);
【问题讨论】:
-
佩德罗,你的问题不太清楚。你想达到什么目的? DynamicJsonArray 有什么问题,所以您需要将它们转换为原始数组类型?为什么要“就地”进行?您如何得知特定 JSON 包含
prop4并且它的实际类型是“整数数组”?我认为如果没有“大局”,就很难回答您的问题。 -
Pedro,对于
[1,2,3,4,5]或["text1", "text2", "text3"]尝试转换为Object[]或ArrayList而不是Array。 -
@BhavikJani
[1,2,3,4,5]和["text1", "text2", "text3"]都以DynamicJsonArray的身份出现。尝试了您建议的转换。当我转换为Object[]时,该对象仍将其类型保持为DynamicJsonArray。当我尝试转换为ArrayList时,C# 告诉我无法将DynamicJsonArray转换为ArrayList。
标签: c# .net arrays json dynamicobject