以gridview格式显示JSON C#

Posted

技术标签:

【中文标题】以gridview格式显示JSON C#【英文标题】:Displaying JSON in a gridview format C# 【发布时间】:2021-12-16 13:04:41 【问题描述】:

我的应用程序收到一个 json 字符串。我希望能够以一种很好的格式化方式显示这个字符串。真的,我什至不知道该问什么问题,这就是我的问题的根源。

这是我收到的字符串示例:

["sentence" : "Goldman Dukes is testing to see whether our request functionality works for the upcoming sprint.","sentenceNbr" : "1","tokens" : ["Goldman", "Dukes", "is", "testing", "to", "see", "whether", "our", "request", "functionality", "works", "for", "the", "upcoming", "sprint", "."],"pos" : ["NNP", "NNP", "VBZ", "VBG", "TO", "VB", "IN", "PRP$", "NN", "NN", "VBZ", "IN", "DT", "VBG", "NN", "."],"ner" : ["PERSON", "PERSON", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O"],"lemmas" : ["Goldman", "Dukes", "be", "test", "to", "see", "whether", "we", "request", "functionality", "work", "for", "the", "upcome", "sprint", "."],"sentence" : "Nick Wills is a great guy.","sentenceNbr" : "2","tokens" : ["Nick", "Wills", "is", "a", "great", "guy", "."],"pos" : ["NNP", "NNP", "VBZ", "DT", "JJ", "NN", "."],"ner" : ["PERSON", "PERSON", "O", "O", "O", "O", "O"],"lemmas" : ["Nick", "Wills", "be", "a", "great", "guy", "."],"sentence" : "He lives in Northern Virginia.","sentenceNbr" : "3","tokens" : ["He", "lives", "in", "Northern", "Virginia", "."],"pos" : ["PRP", "VBZ", "IN", "NNP", "NNP", "."],"ner" : ["O", "O", "O", "LOCATION", "STATE_OR_PROVINCE", "O"],"lemmas" : ["he", "live", "in", "Northern", "Virginia", "."]]

我收到的字符串与上面完全相同,没有空格或其他格式帮助。这是一个稍微易读的版本:

[
  
    "sentence" : "Goldman Dukes is testing to see whether our request functionality works for the upcoming sprint.",
    "sentenceNbr" : "1",
    "tokens" : ["Goldman", "Dukes", "is", "testing", "to", "see", "whether", "our", "request", "functionality", "works", "for", "the", "upcoming", "sprint", "."],
    "pos" : ["NNP", "NNP", "VBZ", "VBG", "TO", "VB", "IN", "PRP$", "NN", "NN", "VBZ", "IN", "DT", "VBG", "NN", "."],
    "ner" : ["PERSON", "PERSON", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O"],
    "lemmas" : ["Goldman", "Dukes", "be", "test", "to", "see", "whether", "we", "request", "functionality", "work", "for", "the", "upcome", "sprint", "."]
  ,
  
    "sentence" : "Nick Wills is a great guy.",
    "sentenceNbr" : "2",
    "tokens" : ["Nick", "Wills", "is", "a", "great", "guy", "."],
    "pos" : ["NNP", "NNP", "VBZ", "DT", "JJ", "NN", "."],
    "ner" : ["PERSON", "PERSON", "O", "O", "O", "O", "O"],
    "lemmas" : ["Nick", "Wills", "be", "a", "great", "guy", "."]
  ,
  
    "sentence" : "He lives in Northern Virginia.",
    "sentenceNbr" : "3",
    "tokens" : ["He", "lives", "in", "Northern", "Virginia", "."],
    "pos" : ["PRP", "VBZ", "IN", "NNP", "NNP", "."],
    "ner" : ["O", "O", "O", "LOCATION", "STATE_OR_PROVINCE", "O"],
    "lemmas" : ["he", "live", "in", "Northern", "Virginia", "."]
  
]

我的最终目标是以 gridview 类型的格式显示这些数据,但现在我会满足于弄清楚如何以“漂亮”的方式显示它,如上所述。

我非常熟悉使用 C#,但没有使用 JSON 的经验。任何帮助将不胜感激

【问题讨论】:

也许这个:nuget.org/packages/FracturedJson 但一般来说,这里认为要求工具推荐的问题是题外话。 你能模拟出你期望这个 GV 的样子吗,可以截个 Excel 吗? 既然您熟悉 C#,这应该是轻而易举的事。想象一下 JSON 是 XML,您将把它反序列化为对象,就像您使用 XML 一样。或者想象它是您从数据库加载的数据。使用 JSON 中的键(“句子”、“令牌”等)等属性定义您的类,然后使用 System.Text.Json (docs.microsoft.com/en-us/dotnet/api/…) 或 Newtonsoft.Json (newtonsoft.com/json) 转换 JSON串成对象。然后像显示任何其他 c# 对象一样显示这些对象。 @CaiusJard 我上传了这可能喜欢的样本 @gnud 属性标记、pos、ner、lemmas 的数据类型都是字符串 [] 吗? 【参考方案1】:

好的,如果你仔细看,我们有前两行,它们是重复数据。

那么下一组列就是一个子表。

实际上,这就是我们所拥有的:

public class Class1

    public string[] sentence  get; set; 
    public string[] sentenceNbr  get; set; 
    public string[][] tokens  get; set; 
    public string[][] pos  get; set; 
    public string[][] ner  get; set; 
    public string[][] lemmas  get; set; 

注意前两列是 string[] 的数组,但最后 4 列实际上是 string[] 的 string[](嵌套数组)。

不幸的是,gridview 不能真正显示它。 但是,gridview、listview、repeater、datalist - 它们都可以占据前两列。

因此,我们可以使用中继器 - 或数据列表(它们在所做的事情上都相当接近 - 重复数据)。

所以,假设我们有这个 DataList:

我只有前两列。

        <asp:Datalist ID="MyDataList" runat="server" OnItemDataBound="MyDataList_ItemDataBound">

         <ItemTemplate>

             <div style="float:left">
                 <h3>Sentance</h3>
                <asp:Label ID="Sentence" runat="server" Text='<%# Eval("sentence") %>'
                    Width="300px" 
                   ></asp:Label>
             </div>
             <div style="float:left">
                 <h3>Nbr</h3>
         <asp:Label ID="sentenceNbr" runat="server" Text='<%# Eval("sentenceNbr") %>' 
             Width="80px"></asp:Label>
             </div>
            </ItemTemplate>
        </asp:Datalist>

现在我们要加载的代码:

    protected void Page_Load(object sender, EventArgs e)
    
        if (!IsPostBack)
            LoadMyData();
    

    void LoadMyData()
    
        string strJSON = "";
        strJSON = File.ReadAllText(@"c:\test7\udata.txt");

        strJSON = " 'myroot' :" + strJSON + "";
        DataSet MyTables = new DataSet();
        MyTables = JsonConvert.DeserializeObject<DataSet>(strJSON);

        MyDataList.DataSource = MyTables;
        MyDataList.DataBind();

    

请注意我是如何向您的 json 数据添加“根”的。

好的,现在我们看到了:

嘿,一点也不差!!!!

现在是附加列 - 它们只是不适用于上面。

但这意味着我们必须嵌套并放入一个网格到上面的 DataList/Repeater 控件中。

好的,让我们这样做。所以到上面,就在前两个标签的正下方,我们放入:

 <div style="margin-left:25px">
   <asp:GridView ID="GridView2" runat="server" 
       CssClass="table table-condensed"></asp:GridView>
 </div>

现在,我们必须把它填满。我真的很想保留这段代码,但我想不出更好的方法(当你需要时,linq 和 lamda 表达式专家在哪里???)。

但是,这似乎可行:

所以我们将使用所谓的数据绑定事件。对于gridview、listview、repeater 等来说,这几乎是一样的(.net 的美妙之处在于,一旦你学会了一个,那么你就会全部了解)。

所以,我们将获取我们正在绑定的当前数据行。

为 4 个多值列创建一个假表 将数据推入那个假表中,然后将表推到那个网格视图中。

它没有太多代码,但非常接近 SO 上的实用限制。

所以,这行得通:

    protected void MyDataList_ItemDataBound(object sender, DataListItemEventArgs e)
    
        GridView gv = (GridView)e.Item.FindControl("GridView2");
        DataRowView OneDataRow = (DataRowView)e.Item.DataItem;
        
        DataTable rstData = new DataTable();
        rstData.Columns.Add("tokens");
        rstData.Columns.Add("pos");
        rstData.Columns.Add("ner");
        rstData.Columns.Add("lemmas");
        
        for (int ChildRow = 0;ChildRow < ((string[])OneDataRow["tokens"]).Length;ChildRow++) 
            // add new row
            DataRow NewRow = rstData.NewRow();
            foreach(DataColumn myCol in rstData.Columns)
            
                // add each column value
                NewRow[myCol.ColumnName] = ((string[])OneDataRow[myCol.ColumnName])[ChildRow].ToString();
            
            rstData.Rows.Add(NewRow);
        
        gv.DataSource = rstData;
        gv.DataBind();
    

不会太糟糕,也不会太乱。

所以,我想你可以在这里看到我们在做什么。

输出:

【讨论】:

如果我自动提取这些数据,你还需要添加 myroot 吗 好吧,您可能不必添加“myroot”(我刚刚为表选择了任何名称),但是如果您环顾网络,我见过的每个 json 字符串都以 并以 结尾。所以你可能会得到一些 json 解析器在没有表名的情况下工作,但你至少需要一个位于 内的字符串 非常感谢您迄今为止的所有帮助。我想对单个“句子”对象使用相同的逻辑。仍然可以使用数据集吗? 这句话只是一个,还是重复? (但是,在这两种情况下都是)。如前所述,我使用了数据集/数据表/数据行。但那是因为我一直在考虑数据库表 - 行和列。 XML 或 json 对我来说总是只是一些表——我从不认为它们是不同的。既然我用像思考的表格来编码转发器、数据列表和网格视图?那么我的解决方案当然是思想和概念上的“表格”。如前所述,您可以考虑使用 list 代替数据集,但我认为它的工作量一样多——通常还要多一点。甚至一个值也会进入数据集。 请记住,数据集是表的集合。所以 DataSet1.Tables[0].Rows[0]["sentence"] 会给你第一个。您还可以学习/使用 json“路径”名称来提取值 - 这将取决于您在代码中尝试执行的操作。所以,在上面的例子中——我把东西移到了数据集,从那时起,gridview 或 datalist 就能够为我做很多处理和肮脏的工作。如前所述,您选择哪条路很大程度上取决于您的需求。我的意思是,也许这里的树视图会很酷! (而且我没有测试一次将树视图绑定到我们的数据集是否是最好的。【参考方案2】:

首先从您的 json 中定义您的 c# 类。你可以使用https://json2csharp.com/

这是你的 c# 类

// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
public class Root

    public string sentence  get; set; 
    public string sentenceNbr  get; set; 
    public List<string> tokens  get; set; 
    public List<string> pos  get; set; 
    public List<string> ner  get; set; 
    public List<string> lemmas  get; set; 

安装Newtonsoft.json 以反序列化它们。

   var data = JsonConvert.DeserializeObject<List<Root>>(jsonAsText);
   dataGridView1.DataSource = data;
   dataGridView1.Refresh();

这种显示数据的非常简单的方式。

【讨论】:

dataGridView1.Refresh(); 可能没有必要。我不认为你会得到一个 datagridview 看起来像这个代码提供的示例.. 你是对的 - gridview 或任何控件都无法处理嵌套数据。有了上面,GV 将只显示前两行。而且您实际上不需要像我上面的代码所示定义一个类 - 您可以定义该类,但无论如何它不会让您走得太远。 另一方面?多么奇妙的问题——完美的面试问题!如何显示这些数据。 仅供参考,从 JSON 或 XML 生成类已内置到 Visual Studio 中。只需创建一个空类文件,将 JSON 字符串复制到剪贴板,然后在您的空 .cs 类文件中转到编辑 > 选择性粘贴 > 将 JSON 粘贴为类 好吧,即使有一个类,你仍然无法让子数据在没有嵌套的情况下显示在网格中。无论如何,如果没有一些工作,您就无法将子数据(4 行)拉出课堂。最终结果是创建课程无济于事。如果这不是主-> 子数据,那么没问题。另一方面,我们看到 newtonsoft 做了同样的工作并吐出列名,甚至没有建立一个类。但是,子数据仍然是个问题。

以上是关于以gridview格式显示JSON C#的主要内容,如果未能解决你的问题,请参考以下文章

asp.net的GridView控件的onrowdeleting属性怎么出错显示为找不到可接受类型。。。呢

在 asp.net 中处理 Gridview 控件中的文本框?

从数据库中提取数据时如何在 GridView 中仅显示日期? C#

在 Gridview 内的 Gridview 上显示 Json

实现gridview空白处的点击事件

我如何在xml中绘制一个框[关闭]