none
JSON to gridview RRS feed

  • Question

  • Hello,

    I am receiving a JSON response from an API that I would like to format into a gridview.  The JSON (at least to me) is complicated due to nesting levels (shown below). 

    I'm using Newtonsoft JSON, and have tried many iterations of direct conversions, but with no luck, for example:

     DataTable dt = (DataTable)JsonConvert.DeserializeObject(result, (typeof(DataTable)));

    I have used json2csharp to create the classes below:

    public class Columns
    {
        public string F4211_DOCO { get; set; }
        public string F4211_ITWT { get; set; }
    }
    
    public class Rowset
    {
        public double F4211_ITWT { get; set; }
        public int F4211_DOCO { get; set; }
    }
    
    public class Summary
    {
        public int records { get; set; }
        public bool moreRecords { get; set; }
    }
    
    public class GridData
    {
        public int id { get; set; }
        public string fullGridId { get; set; }
        public Columns columns { get; set; }
        public List<Rowset> rowset { get; set; }
        public Summary summary { get; set; }
    }
    
    public class Data
    {
        public GridData gridData { get; set; }
    }
    
    public class FsDATABROWSEF4211
    {
        public string title { get; set; }
        public Data data { get; set; }
        public List<object> errors { get; set; }
        public List<object> warnings { get; set; }
    }
    
    public class ServiceRequest1
    {
        public FsDATABROWSEF4211 fs_DATABROWSE_F4211 { get; set; }
        public int stackId { get; set; }
        public int stateId { get; set; }
        public string rid { get; set; }
        public string currentApp { get; set; }
        public string timeStamp { get; set; }
        public List<object> sysErrors { get; set; }
    }
    
    public class RootObjectNew
    {
        public ServiceRequest1 ServiceRequest1 { get; set; }
    }
      var result2 = JsonConvert.DeserializeObject<RootObjectNew>(result);
      

    Using this code formats the data appropriately into result2 (if I look at result2 in debug, I can see there are columns and rows and data is loaded appropriately) but I'm not sure how to get 'result2' into a datagrid. 


    Any help would be appreciated.  

    Thanks.  

    {
      "ServiceRequest1" : {
        "fs_DATABROWSE_F4211" : {
          "title" : "Data Browser - F4211 [Sales Order Detail File]",
          "data" : {
            "gridData" : {
              "id" : 53,
              "fullGridId" : "53",
              "columns" : {
                "F4211_DOCO" : "Order Number",
                "F4211_ITWT" : "Unit Weight"
              },
              "rowset" : [ {
                "F4211_ITWT" : 1.15,
                "F4211_DOCO" : 2332768
              }, {
                "F4211_ITWT" : 3.45,
                "F4211_DOCO" : 2332768
              }, {
                "F4211_ITWT" : 0.0623,
                "F4211_DOCO" : 2332768
              }, {
                "F4211_ITWT" : 0.19,
                "F4211_DOCO" : 2332768
              }, {
                "F4211_ITWT" : 0.12,
                "F4211_DOCO" : 2332768
              } ],
              "summary" : {
                "records" : 5,
                "moreRecords" : false
              }
            }
          },
          "errors" : [ ],
          "warnings" : [ ]
        },
        "stackId" : 1,
        "stateId" : 1,
        "rid" : "eb8117ef4a4662b7",
        "currentApp" : "DATABROWSE_F4211",
        "timeStamp" : "2019-05-13:08.21.06",
        "sysErrors" : [ ]
      }
    }



      
    • Edited by bairdmar Monday, May 13, 2019 1:45 PM
    Monday, May 13, 2019 12:42 PM

All replies

  • GridView as in an ASP.NET application? Please post questions related to ASP.NET in the ASP.NET forums.

    Michael Taylor http://www.michaeltaylorp3.net

    Monday, May 13, 2019 1:38 PM
    Moderator
  • Well, the gridview is my end goal, but if I can get the data into a C# datatable or dataset I can get it to a gridview from there.  I'm struggling to get my JSON response into a datatable.  
    Monday, May 13, 2019 3:33 PM
  • I think you're mixing up layers here so it is going to be harder than you think. The first decision you need to make is whether you want business objects (like you posted) or a Datatable. Don't mix the two.

    Datatables are good for storing in-memory data when you don't want to build out business objects because you don't need them. They are also useful when working with unknown layouts of data (such as arbitrary queries). However they have overhead involved in storing data so they are not good for large sets of data. Datasets (of which data tables are generally a part of) are good at storing related tables together and have some flexibility in constraints. Furthermore it is very easy to make batches of changes to a table and then push it back to a database.

    If you need to enforce any business rules then business objects are the preferred approach. Business objects are more code to write but generally easier to work with. They also can store the data in whatever format fits your needs best and can enforce whatever rules you want to apply. The downside, beside the extra code, is that you are responsible for loading/saving the data back. My personal preference, especially when coming from JSON, is to use business objects.

    Once you've determined business object vs datatable then it is pretty straightforward to bind to a UI control. All grid-like UI controls support binding to either datasets or arbitrary collections of objects. If you want to be able to add/delete then you'll be using a List<T> or Collection<T> but otherwise the controls won't have any issues.

    So, do you want to use business objects that you've already created (in which case you can move on to binding to the UI) or convert to a datatable (in which case you can get rid of the business objects and convert directly from JSON to a datatable)?


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, May 13, 2019 3:55 PM
    Moderator
  • I see, that distinction is helpful.  A business object will work well for my scenario.  However, I still struggle to use this effectively, as the structure of my JSON does not allow me to create a list such as;

    var data = JsonConvert.DeserializeObject<List<RootObjectNew>>(result);

    *the above errors 

    And without a list or collection, I don't know how to use this object properly.   

     
    Monday, May 13, 2019 5:29 PM
  • Given your original JSON I would expect the above code to fail. In JSON a single object is wrapped in curlies. For an array of items you must use [] around it. If you do that then JSON.NET will convert it automatically to a List<T> or IEnumerable<T> or T[], depending upon what you ask for.

    Given your JSON it is a single object that has a ServiceRequest object inside it. If you expect more than one ServiceRequest object you need to wrap it in an array. Note that this should be handled by the code generating the JSON so it shouldn't be a problem.

    [
        {
            "ServiceRequest1": {
                "fs_DATABROWSE_F4211": {...},
                "stackId": 1,
                "stateId": 1,
                "rid": "eb8117ef4a4662b7",
                "currentApp": "DATABROWSE_F4211",
                "timeStamp": "2019-05-13:08.21.06",
                "sysErrors": []
            }
        }
    ]


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, May 13, 2019 5:44 PM
    Moderator
  • Well, the gridview is my end goal, but if I can get the data into a C# datatable or dataset I can get it to a gridview from there.  I'm struggling to get my JSON response into a datatable.  

    It would be better if you use a custom object with public properties loaded in to a collection, becuase a collection of objects are bindable to a control too. And besides, .NET is more geared towards generic collections,  and Visual Studio is too.

    The data coming back from the WebAPI is a Json array of DtoProject that needs to be deserialized and loaded into a List<T> of Dtoproject(s) that is eventually bindable to a ASP.NET Web control.

    https://dzone.com/articles/reasons-move-datatables

    public List<DtoProject> GetProjsByUserIdApi(string userid)
            {
                var dtoprojects = new List<DtoProject>();
    
                using (var client = new HttpClient())
                {
                    var uri = new Uri("http://progmgmntcore2api.com/api/project/GetProjsByUserId?userid=" + userid);
    
                    var response = client.GetAsync(uri).Result;
    
                    if (!response.IsSuccessStatusCode)
                        throw new Exception(response.ToString());
    
                    var responseContent = response.Content;
                    var responseString = responseContent.ReadAsStringAsync().Result;
    
                    dynamic projects = JArray.Parse(responseString) as JArray;
    
                    foreach (var obj in projects)
                    {
                        DtoProject dto = obj.ToObject<DtoProject>();
    
                        dtoprojects.Add(dto);
                    }
                }
    
                return dtoprojects;
            }

    using System;
    
    namespace Entities
    {
        public class DtoProject
        {
            public int ProjectId { get; set; }
            public string ClientName { get; set; }
            public string ProjectName { get; set; }
            public string Technology { get; set; }
            public string ProjectType { get; set; }
            public string UserId { get; set; }
            public DateTime StartDate { get; set; }
            public DateTime EndDate { get; set; }
            public decimal Cost { get; set; }
        }
    }
    

    Tuesday, May 14, 2019 1:41 AM

  • Hi    bairdmar,

    Thank you for posting here.

    >>but if I can get the data into a C# datatable or dataset I can get it to a gridview from there.  I'm struggling to get my JSON response into a datatable. 

    DataTable display data with rows and columns, but the Json data is nested, it means you cannot see the all contents with only  one datatable.

    I have made a simple in my side and I use some DataTables to show the Json data.

    Here are the two results of test  in datagridview:

    1.DataTable to show the message in ‘ServiceRequest1’:



    2.DataTable to show the message in ‘fs_DATABROWSE_F4211’:




    Best Regards

    Yong Lu

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, May 15, 2019 9:11 AM
    Moderator