【问题标题】:How to create column and row wise json structure?如何创建列和行明智的 json 结构?
【发布时间】:2016-08-19 13:21:51
【问题描述】:

我正在尝试创建如下所示的 json 结构:

{
  "cols": [
    {
      label: "Types",
      type: "string"
    },
    {
      label: "values",
      type: "number"
    }
  ],
  "rows": [
    {
      c: [
        {
          v: "Mushrooms"
        },
        {
          v: 3
        },
        
      ]
    },
    {
      c: [
        {
          v: "Olives"
        },
        {
          v: 31
        }
      ]
    },
    {
      c: [
        {
          v: "Zucchini"
        },
        {
          v: 1
        },
        
      ]
    },
    {
      c: [
        {
          v: "Pepperoni"
        },
        {
          v: 2
        },
        
      ]
    }
  ]
}

我从这里得到的上述值:

public class Type
{
    public int Mushrooms { get; set; }
    public int Olives { get; set; }
    public int Zucchini { get; set; }
    public int Pepperoni { get; set; }
  public int Statistics { get; set; } //Ignore properties in final output
    public int Count { get; set; } //Ignore properties in final output
    public int Average { get; set; } //Ignore properties in final output
}

var types = MyRepository<Type>.FirstorDefault();

以上查询输出:

蘑菇:3

橄榄:31 等。

这就是我设计课程的方式:

public class Cols
{
    public List<Names> Names { get; set; }

}

public class Names
{
    public string label { get; set; }
    public string type { get; set; }
}

但我得到这样的输出:

"data": [
    {
      "Names": [
        {
          "label": "Types",
          "type": "string"
        },
        {
          "label": "values",
          "type": "number"
        }
      ]
    }
  ]

更新:类设计

 public class Rootobject
    {
        public List<Names> cols { get; set; }
        public List<Row> rows { get; set; }
    }

    public class Names
    {
        public string label { get; set; }
        public string type { get; set; }
    }

    public class Row
    {
        public List<C> c { get; set; }
    }

    public class C
    {
        public object v { get; set; } 
    }

上面的类设计给了我下面的 json 结构:

{
  "Data": {
    "cols": [
      {
        "label": "Types",
        "type": "string"
      },
      {
        "label": "values",
        "type": "number"
      }
    ],
    "rows": [
      {
        "c": [
          {
            "v": "Mushrooms"
          },
          {
            "v": "3"
          },
          {
            "v": "Olives"
          },
          {
            "v": "31"
          },
          {
            "v": "Zucchini"
          },
          {
            "v": "1"
          },
          {
            "v": "Pepperoni"
          },
          {
            "v": "2"
          }
        ]
      }
    ]
  }
}

为了返回 json 数据,我正在使用这个 json 的 asp.net mvc 类。

return Json(new {Data = rootObject }, JsonRequestBehavior.AllowGet);

【问题讨论】:

    标签: c# .net json linq


    【解决方案1】:

    您更新的类设计可以代表您需要的 JSON。问题是,如何分配和初始化你的Rootobject的内容?您可以使用reflection 执行此操作,特别是通过使用Type.GetProperties() 循环遍历Rootobject 的所有公共属性,然后使用PropertyInfo.GetValue() 查询值,如下所示:

    var query = types.GetType()
        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .Where(p => p.GetIndexParameters().Length == 0 && p.GetGetMethod() != null && p.CanRead)
        .Select(p => new Row { c = new List<C> { new C { v = p.Name }, new C { v = p.GetValue(types, new object[0]) } } });
    
    var root = new Rootobject
    {
        cols = new List<Names> { new Names { label = "Types", type = "string" }, new Names { label = "values", type = "number" } },
        rows = query.ToList(),
    };
    
    return Json(root, JsonRequestBehavior.AllowGet);
    

    示例fiddle。

    如果您有要忽略的特定属性名称列表,您可以将这些名称添加到哈希集中并过滤掉它们:

    var ignoredPropertyNames = new HashSet<string> { "Statistics", "Average", "Count" };
    
    var query = types.GetType()
        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .Where(p => p.GetIndexParameters().Length == 0 && p.GetGetMethod() != null && p.CanRead)
        .Where(p => !ignoredPropertyNames.Contains(p.Name))
        .Select(p => new Row { c = new List<C> { new C { v = p.Name }, new C { v = p.GetValue(types, new object[0]) } } });
    

    或者,如果您要包含特定的属性名称列表,则可以使用Type.GetProperty(string) 获取相应的属性并像以前一样继续:

    var propertyNames = new[] { "Mushrooms", "Olives", "Zucchini", "Pepperoni" };
    
    var query = propertyNames
        .Select(n => types.GetType().GetProperty(n))
        .Where(p => p != null)
        .Where(p => p.GetIndexParameters().Length == 0 && p.GetGetMethod() != null && p.CanRead)
        .Select(p => new Row { c = new List<C> { new C { v = p.Name }, new C { v = p.GetValue(types, new object[0]) } } });
    

    【讨论】:

    • 在这种类型的类中,我有 3 个额外的属性进入输出。是否可以避免这些属性。例如:这些属性是统计、计数、平均值。我想避免这 3 个属性我的输出。这可能吗??
    • @Learning - 是的,可以做到。但首先请尝试提供一个minimal reproducible example 来重现您的问题。您是否事先知道要序列化的硬编码属性集,或者您想用attributes 标记您的类,指示要序列化或忽略哪个属性?
    • 是的,我事先知道,为了创建这个 json 结构,我想忽略统计、计数和平均值,但我在其他地方使用这 3 个属性。所以我只想忽略这个 json 结构的这 3 个属性only.See 我更新的问题现在包括完整的 Type 类
    【解决方案2】:

    根据您的第一个 json,如果您想以这种方式序列化它,您的类结构应该是这样的:

    public class Rootobject
    {
        public List<Names> cols { get; set; }
        public List<Row> rows { get; set; }
    }
    
    public class Names
    {
        public string label { get; set; }
        public string type { get; set; }
    }
    
    public class Row
    {
        public List<C> c { get; set; }
    }
    
    public class C
    {
        public string v { get; set; }
    }
    

    【讨论】:

    • 但是在这里生成行数组时,我将如何添加蘑菇、橄榄等,因为您已将 v 声明为 int
    • @Learning 抱歉已修复
    • 对不起,但是你的类设计我没有得到预期的 json 架构
    【解决方案3】:

    如here 所述,您可以对动态对象进行反序列化并使用该对象,这样您就无需在不需要的地方编写补充代码:

    dynamic obj = JObject.Parse(yourComplexJson);
    

    【讨论】:

      猜你喜欢
      • 2014-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-28
      • 1970-01-01
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多