如何使用DynamicJsonObject的属性值?

时间:2017-05-18 20:19:30

标签: c# .net arrays json dynamicobject

让我们说在我的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并将信息发送到数据库。

我的主要问题是处理prop4prop5等属性。此数组正在转换为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);

1 个答案:

答案 0 :(得分:0)

它只是读取从API返回的json对象。

例如

您可以使用

dynamic stuff = JsonConvert.DeserializeObject("{ 'prop1' : 'sometext', 'prop2': '123',
    'prop3': 'True'}");

string Prop1= stuff.First.Prop1;
string Prop2= stuff.First.Prop2;

// For that you will need to add reference to System.Web.Helpers
dynamic json = System.Web.Helpers.Json.Decode(@""{ 'prop1' : 'sometext', 'prop2': '123',
    'prop3': 'True'}"");
Console.WriteLine(json.prop1);

Stackoverflow中的另一个类似问题如下 How can I parse JSON with C#?