Nathan
Nathan

Reputation: 71

JsonConvert ends function

I am trying to convert a stringified json object from the front end passed into the middle tier. I'm using NewtonSoft.Json.JsonConvert.DeserializeObject. I get no errors. But, when I set a breakpoint, I see that the function exits at the call to deserialize. It does not proceed any further. Here's my code.

public class tranx
{
    public Transaction transaction { get; set; }
    public List<LineItem> lineItems { get; set; }
}

[HttpGet]
public ActionResult saveTransaction(string transactionJson)
{
    tranx t = JsonConvert.DeserializeObject<tranx>(transactionJson);
    foreach (LineItem i in t.lineItems)
    {
        if (i != null)
        {
            Console.Write(i.CategoryID);
        }
    }
     return View();
}

NOTE: Transaction and LineItem are also objects I have defined and are accessible.

I'm not sure why the code exits before the foreach loop. Any thoughts?

Here is the json string:

{
   "transaction":[
      {
         "entityID":"",
         "date":"2018-05-28"
      }
   ],
   "lineItems":[
      {
         "category":"",
         "subCategory":"",
         "amount":"",
         "tax":0,
         "description":"",
         "miles":"",
         "gallons":""
      },
      {
         "category":"",
         "subCategory":"",
         "amount":"",
         "tax":0,
         "description":"",
         "miles":"",
         "gallons":""
      }
   ]
}

Also, I'm not using any custom deserializer.

Upvotes: 0

Views: 377

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500385

I believe what's actually happening is that an exception like this is being thrown:

Unhandled Exception: Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Transaction' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

This is due to your JSON which specifies the transaction property as an array:

"transaction":[{"entityID":"","date":"2018-05-28"}]

... whereas your transaction property is just a single Transaction.

Here's sample code to show that - just put your sample JSON in test.json:

using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;

public class tranx
{
    public Transaction transaction { get; set; }
    public List<LineItem> lineItems { get; set; }
}

public class LineItem { }
public class Transaction { }

class Program
{
    static void Main()
    {
        string json = File.ReadAllText("test.json");
        tranx t = JsonConvert.DeserializeObject<tranx>(json);
    }
}

So, you have two problems to fix:

  • Assuming your JSON is correct, your tranx class needs to change so that its transaction property is a list or array, e.g.

    public List<Transaction> transaction { get; set; }
    
  • You should work out why you weren't able to see the exception. This is really important. If exceptions are being thrown and you can't see them, it's going to be very hard to maintain the code. This is actually the first thing I'd fix.

I'd also strongly advise you to follow .NET naming conventions, where properties and type names are capitalized. You can use the [JsonProperty] attribute to specify how values should be represented in JSON, if that was the reason for the properties being lower case before.

Upvotes: 1

Related Questions