1

This is my first question on Stackoverflow. I am learning C# and I build a simple bank console app in C#. A small menu was created where one of the options is to allow the user create a bank account and it gets saved in a json file.

A sample of the saved user inputs into the json file is as such:

{
    "FirstName": "Ari",
    "LastName": "Man",
    "Pin": 1122,
    "Balance": 400.0
}
{
    "FirstName": "Tari",
    "LastName": "Man",
    "Pin": 3434,
    "Balance": 566.89
}
{
    "FirstName": "Mari",
    "LastName": "Man",
     "Pin": 5656,
    "Balance": 677.0
}

My code is:

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

namespace BankApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string selection;
            //int _initPin;
            double newBalance;

            //create bank object
            Accounts bank = new Accounts();

            //display menu
            while (true)
            {
                Console.WriteLine("=======================================");
                Console.WriteLine("Welcome to Banko - your online Bank App");
                Console.WriteLine("=======================================\n");
                Console.WriteLine("1. Account Balance\n");
                Console.WriteLine("2. Open an account\n");
                Console.WriteLine("3. Withdraw\n");
                Console.WriteLine("4. Deposit\n");
                Console.WriteLine("5. Exit\n\n");

                Console.WriteLine("Select an option:\n ");
                selection = Console.ReadLine();

                if (selection == "5")
                {
                    Console.WriteLine("Thank You! Hope to see you soon");
                    Console.ReadLine();
                    break;
                }
                else
                    switch (selection)
                    {
                        case "1":
                            Console.WriteLine(Deserialize());
                            break;

                        case "2":
                            Console.WriteLine("Enter your first name: ");
                            bank.FirstName = Console.ReadLine();
                            Console.WriteLine("Enter your last name: ");
                            bank.LastName = Console.ReadLine();
                            Console.WriteLine("Enter a new new PIN: ");
                            bank.Pin = int.Parse(Console.ReadLine());
                            Console.WriteLine("Enter starting balance: ");
                            bank.Balance = double.Parse(Console.ReadLine());
                            break;

                        case "3":
                            newBalance = bank.Withdraw();
                            Console.WriteLine("Your current balance is: {0}", newBalance + Environment.NewLine);
                            break;

                        case "4":
                            newBalance = bank.Deposit();
                            Console.WriteLine("Your current balance is: {0}", newBalance + Environment.NewLine);
                            break;
                    }
            }


            //serialize JSON file and write to json file
            string filePath = @"C:\Users\shakazul\source\repos\BankApp\accounts.json";
            string output = JsonConvert.SerializeObject(bank, Formatting.Indented);
            File.AppendAllText(filePath, output + Environment.NewLine);
        }

        public static Accounts Deserialize()
        {
            //path to JSON file and read file
            string filePath = @"C:\Users\shakazul\source\repos\BankApp\accounts.json";
            string jsonResults = File.ReadAllText(filePath);

            //Deserialize the JSON file to an object
            Accounts results = JsonConvert.DeserializeObject<Accounts>(jsonResults);
            return results;
        }
    }
}

My class is:

namespace BankApp
{
    public class Accounts
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Pin { get; set; }
        public double Balance { get; set; }

        public Accounts()
        {
            this.FirstName = FirstName;
            this.LastName = LastName;
            this.Pin = Pin;
            this.Balance = Balance;
        }
   
        public double Deposit()
        {
            double deposit;
            double newBalance;

            Console.WriteLine("Please enter amount to deposit: ");
            deposit = double.Parse(Console.ReadLine());

            newBalance = Balance + deposit;

            return newBalance;
        }

        public double Withdraw()
        {
            double newBalance;
            double withdraw;

            Console.WriteLine("Please enter amount to withdraw: ");
            withdraw = double.Parse(Console.ReadLine());

            newBalance = Balance - withdraw;

            return newBalance;
        }
    }
}

So my issue is that when I was get parse the json file and get the account balance of a certain customer based on the PIN they entered, I get an error

Newtonsoft.Json.JsonReaderException: 'Additional text encountered after finished reading JSON content: {. Path '', line 6, }

So if I had only one entry, I can retrieve the balance value, but more than that and I get the error that happens at:

Accounts results = JsonConvert.DeserializeObject<Accounts>(jsonResults); 

line of the code.

Any help would be greatly appreciated.

2
  • 3
    Two things to look at: Your example JSON does not look to be in the format of and array so would not be valid, and your Accounts object is singular and you do not attempt to read a collection of them. Commented Oct 24, 2020 at 1:13
  • Thank you for your reply, I see what you mean. Commented Oct 24, 2020 at 3:49

1 Answer 1

1

The main issue that you are dealing with is that you're trying to create JSON by manually appending it instead of serializing a collection of objects into JSON.

To explain, when you are saving new objects, they look like this:

//JsonDeserializer reads this as start of document.
{ "FirstName": "Ari",
  "LastName": "Man",
  "Pin": 1122,
  "Balance": 400.0 
} 
//JsonDeserializer reads this as end of document.

{ //Document already ended, what to do with this??? JsonDeserializer throws exception. 
"FirstName": "Tari",
  "LastName": "Man",
  "Pin": 3434,
  "Balance": 566.89 
} 
{ "FirstName": "Mari",
  "LastName": "Man",
  "Pin": 5656,
  "Balance": 677.0
}

This isn't valid JSON (well not a singular valid JSON document). JSON serializers can't detect the second object, because there's nothing that's telling them to expect an object there. Instead, what you want to do is take all of the objects and put them in an array, like so.

[
{"FirstName: "Ari", "Last"...}, //the commas tell the deserializer to expect more objects
{"FirstName: "Tari", "Last"...},
{"FirstName: "Mari", "Last"...}
]

HOWEVER, you don't have to do this by hand. Newtonsoft.Json automatically builds the JSON for you when you serialize an object. What you need to do is to tell Newtonsoft that you want an array. To do that, take your Accounts object and put it into a Collection, like a List.

var accounts = new List<Accounts>();
accounts.Add(bank);

You can then serialize this List into JSON and save it! This list can then be deserialized back into a List, to which you can add more accounts.

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent, this is well explained. I know what to do now. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.