【问题标题】:C# If a condition is met, use the result and run it through the same methodC# 如果满足条件,则使用结果并通过相同的方法运行它
【发布时间】:2018-08-03 13:31:26
【问题描述】:

我正在轮询 API,这些 API 以相同的格式返回不同类型的 JSON 字符串,这些字符串包含列表、列表内、列表内。这是一个例子:

[
    {
        "name": "string",
        "production": true,
        "start_timestamp": "string",
        "end_timestamp": "string",
        "width": 0,
        "height": 0,
        "scale": 0,
        "floors": [
            {
                 "number": 0,
                 "display_name": "string",
                 "map_image_url": "string",
                 "inside_image_url": "string",
                 "zone_maps": [
                     {
                         "name": "string",
                         "display_name": "string",
                         "zone_image_url": "string",
                         "zones": [
                             {
                                 "name": "string",
                                 "display_name": "string",
                                 "color": "string"
                             }
                         ]
                     }
                 ]
             }
         ]
     }
]

我正在尝试为所有 API 创建一个动态方法,该方法可以获取第一个列表的所有属性的值并将它们连接成 csv 的字符串。然后,如果在这些属性中找到另一个列表,请再次执行相同的方法,直到没有更多列表为止。这是我当前的示例代码:

    public static string DelimetedString(object obj)
    {
        List<string> lineItem = new List<string>();

        Type myObject = obj.GetType();

        foreach (var v in myObject.GetProperties())
        {
            var objType = v.PropertyType.Name;
            if (objType.Contains("List"))
            {                  
                DelimetedString(v); //It is here where I would like to loop through the next list                                 
            }
            else
            {
                var value = v.GetValue(obj, null);
                if (value == null)
                {
                    lineItem.Add("");
                }
                else
                {
                    lineItem.Add(value.ToString());
                }
            }
        }
        return string.Join(",", lineItem);
    }

最终目标是让列标题包含属性名称,以及此下每个属性的数据以分隔格式。提前感谢您的帮助!

编辑:对不起,我应该对此进行扩展。我确实使用 Newtonsoft 反序列化为 json 对象。

MyClass _myObject = JsonConvert.DeserializeObject<MyClass>(responseJson);   

然后我将该对象发送到 DelimitedString() 函数。

【问题讨论】:

  • 米切尔,你是怎么做到的?

标签: c# json properties generic-list


【解决方案1】:

对于这样的问题,你可以做两件事:

  • 为传入的 json 对象创建数据模型,或者
  • 使用“动态”类型的对象

我强烈建议使用 Newtonsoft 的 Json.NET 来反序列化 json。 https://www.newtonsoft.com/json

【讨论】:

  • 对不起,我应该对此进行扩展。我确实序列化了 json 响应,请参阅编辑。干杯!
【解决方案2】:

这个怎么样?

public static string GetCsvFromJson(JToken node)
{
    var result = "";

    if (!node.HasValues)
        return node.ToString();

    foreach (var child in node.Children())
    {
        result += GetCsvFromJson(child) + ",";
    }

    return result.TrimEnd(',');
}

调用它:

string commaSeparatedValues = GetCsvFromJson(JToken.Parse(yourJsonString));

如果您已经序列化了 json 值,那么我将尝试编辑您的函数。如果它包含列表,而不是检查类型名称,它是不安全的顺便说一句,您可以更进一步,直到对象是值类型或字符串(字符串是引用类型):

    public static string DelimetedString(object obj)
    {
        var result = "";

        if (obj.GetType().IsValueType || obj is string)
            return obj.ToString();

        if (obj is IEnumerable)
        {
            foreach (var item in (IEnumerable)obj)
            {
                result += DelimetedString(item) + ",";
            }
        }
        else
        {
            foreach (var prop in type.GetProperties())
            {
                result += DelimetedString(prop.GetValue(obj)) + ",";
            }
        }

        return result.TrimEnd(',');
    }

【讨论】:

  • 这是一种非常酷的方法,对于简单的 json 字符串非常有效。但是它仍然有同样的问题,如果它遇到一个列表,它会将列表添加为值。
  • @MitchellStone 它绕过列表值并进入内部节点,直到达到值。你测试过吗?
  • @MitchellStone 请检查我的最终答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-11
  • 2017-05-13
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多