Solved

converting a dataset to JSON using json.net

Posted on 2014-12-08
12
414 Views
Last Modified: 2014-12-11
This is a somewhat related question to my previous thread found here.

My next step that I want to accomplish is to take a dataset and convert it's contents into a JSON object, where I can then "loop" through each object and manipulate the data. being extremely new to .NET, I'm sure I'm missing a piece or two in my solution :)

I'm able to fill up my data set with nor problem, and verified this through the dataset visualizer. The code I'm using to convert my dataset is:

        private PendingOrders getOrdersToProcess(DAL_Class dbHelper)
        {
            var json = JsonConvert.SerializeObject(dbHelper.getPendingOrders(_mode));
            return JsonConvert.DeserializeObject<PendingOrders>(json);

        }

Open in new window


and my PendingOrders class:

    public class PendingOrders
    {
        public int orderID                          { get; set; }
        public int dataID                           { get; set; }
        public string recipientEmail                { get; set; }
        public string instructions                  { get; set; }
        public DateTime needBy                      { get; set; }
        public string recipientName                 { get; set; }
        public string company                       { get; set; }
        public string recipientPhone                { get; set; }
        public string address1                      { get; set; }
        public string address2                      { get; set; }
        public string City                          { get; set; }
        public string StateProv                     { get; set; }
        public string Country                       { get; set; }
        public string PostalCode                    { get; set; }
        public string CCG_Sku                       { get; set; }
        public int quantity                         { get; set; }
    }

Open in new window


the dbHelper.getPendingOrders() function fills up the dataset and returns it. if I run the following code:

var po = new PendingOrders();
po = getOrdersToProcess(dbHelper);

Open in new window


none of my data is in the po object, everything is null.

So I guess my first question is why? the JSON being returned is multiple objects (each row is it's own object). Do I need to create some kind of collection of objects here? If so, what's the best way to do that?

my second question is once I have this data converted over to some kind of (collection of) object(s), how can I loop through it and read each individual object?
0
Comment
Question by:Big Monty
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 2
12 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40488024
What is the return type of getPendingOrders?
0
 
LVL 33

Author Comment

by:Big Monty
ID: 40488027
It returns a data set
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40488078
Then that's your problem:  You cannot mix types--generally--when serializing. A DataSet is not a PendingOrders, so it's not going to get serizlized into one by the serializer. You'll need to perform some mapping of your DataSet into a collection of PendingOrders.
0
How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

 
LVL 33

Author Comment

by:Big Monty
ID: 40488113
the line:

var json = JsonConvert.SerializeObject(dbHelper.getPendingOrders(_mode));

creates a string of all of the json data. I thought when I called the Deserialize function, it did the mapping for me...

Is there a better, more efficient way to do this? My end goal is to take some data from the database and put it in a JSON object so that I can use it at different points in my program
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 400 total points
ID: 40488137
creates a string of all of the json data. I thought when I called the Deserialize function
This line:

var json = JsonConvert.SerializeObject(dbHelper.getPendingOrders(_mode));

...does do that. But this line:

JsonConvert.DeserializeObject<PendingOrders>(json);

...does not do what you intend it to do. If getPendingOrders returned a PendingOrders object, then that line would work. Unfortunately, you said that it returns a DataSet. DataSet != PendingOrders. If your goal is to transmit data across the wire, then honestly I would ditch the DataSet, and just populate a collection of (what I shall call) your entity class (i.e. PendingOrders).

e.g.

public class DAL_Class 
{
    public IEnumerable<PendingOrders> getPendingOrders()
    {
        List<PendingOrders> orders = new List<PendingOrders>();
        
        using (SqlConnection con = new SqlConnection("your connection string"))
        {
            using (Sqlcommand cmd = new SqlCommand("your query", con))
            {
                try
                {
                    SqlDataReader reader;
                    
                    con.Open();
                    reader = cmd.ExecuteReader();
                    
                    while (reader.Read())
                    {
                        PendingOrders order = new PendingOrders();
                        
                        order.orderID = (int)reader["orderId column name"];
                        order.dateID = (int)reader["dateId column name"];
                        // etc.
                        
                        orders.Add(order);
                    }
                }
                catch (SqlException)
                {
                    // Handle exception
                }
            }
        }
        
        return orders;
    }
}

Open in new window



Side Note: Not that there's anything wrong with it from a functional point of view, but the convention in .NET is to use Pascal-style naming for classes, methods, and properties. Camel-casing is reserved for variable/field names. As I said, it's not broken, but don't be surprised if someone else mentions it  ; )
0
 
LVL 10

Assisted Solution

by:Walter Padrón
Walter Padrón earned 100 total points
ID: 40489288
IMHO if you are moving data between layers in your own application you better stick with a collection so you don't need to serialize and deserialize;   json is more suitable to move data between different platforms or over internet.

You can iterate over a collection with the foreach statement
0
 
LVL 33

Author Comment

by:Big Monty
ID: 40489364
@Kaufmed

thank you for that bit of code, I'm currently tying it into my project and getting it to work. I guess that was the answer to my question "what is the best collection to use when I want to take data from the database and keep in memory for later use?" what I'm ultimately trying to do is take a list of orders from the database with a status of pending, then call a 3rd party web service that returns the number of items in stock for each item ordered. as long as the number ordered is less than what's in stock, I'll call another web service and place the order

@WP

Agreed. It was a more of a learning exercise that I started off that way than anything else.
0
 
LVL 33

Author Comment

by:Big Monty
ID: 40489374
By the way, my code for calling the new getPendingOrders() function (I'm just so used to camel case!) is below. Does that look correct?

IEnumerable<PendingOrders> PendingOrders = new List<PendingOrders>();
PendingOrders = dbHelper.getPendingOrders(_mode);

Open in new window

0
 
LVL 75

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 400 total points
ID: 40489405
I don't see any errors. From a stylistic point of view:

There's no reason to initialize a new list as your first operation. The very next line assigns the result of the method call to the list, so the first initialization is really pointless. My suggestion is to collapse it into a single line:
IEnumerable<PendingOrders> PendingOrders = dbHelper.getPendingOrders(_mode);
It might be confusing to have a variable name that is the same name as a class--and in some cases it's a compiler error; surprised you're not seeing such. This is where the camel casing would come into play
IEnumerable<PendingOrders> pendingOrders = dbHelper.getPendingOrders(_mode);

Also, IMO your class name should be singular:  PendingOrder. A collection of those classes would be plural.
0
 
LVL 10

Expert Comment

by:Walter Padrón
ID: 40489411
Ahh, OK.  I suggest learn LINQ and/or EF next.

You can do something like this
var  context = new DatabaseContext();
var results = from o in context.Orders
                         where o.OrderID < 100
                         select ConvertToPendingOrders(o);

Open in new window

0
 
LVL 33

Author Closing Comment

by:Big Monty
ID: 40492457
thanks to both experts for clear concise answers and explanations!
0
 
LVL 33

Author Comment

by:Big Monty
ID: 40494393
I've added another question if you have any time to look at it:

http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_28579056.html
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question