Simple json editor using c#

editor

I have created a sample project to read json file, edit and save into another file using c# and Newtonsoft.Json library. If anyone want this kind of implementation, you can download project and continue. I have added the sample json file with the project into my Github repository.

Github repository

I have json file format like below.

{
"tasks": [{
"AccountName": "testaccount",
"AccountKey": "0de5edbc-6a02-4450-a139-33d4e760a257",
"ContainerName": "1234",
"RootPath": "/",
"DaysOfHistoryToKeep": 10
}, {
"AccountName": "test2",
"AccountKey": "f15c414b-734a-4a4e-b1a6-eb0794df4e46",
"ContainerName": "2345",
"RootPath": "/",
"DaysOfHistoryToKeep": 15
}]
}

According to that json structure, i am going to build my object structure like below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JsonEditor
{
    public class Task
    {
        public string AccountName { get; set; }
        public string AccountKey { get; set; }
        public string ContainerName { get; set; }
        public string RootPath { get; set; }
        public int DaysOfHistoryToKeep { get; set; }
    }
}

And I have Tasks class which contains list of Task classes.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JsonEditor
{
    public class Tasks
    {
        public List<Task> tasks { get; set; }
    }
}

This is how program going to read the json file and convert into list and bind into grid.

Stream myStream = null;
            OpenFileDialog theDialog = new OpenFileDialog();
            theDialog.Title = "Open Text File";
            theDialog.Filter = "JSON files|*.json";
            theDialog.InitialDirectory = @"C:\";
            if (theDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    if (theDialog.FileName.Trim() != string.Empty)
                    {
                        using (StreamReader r = new StreamReader(theDialog.FileName))
                        {
                            string json = r.ReadToEnd();
                            Tasks items = JsonConvert.DeserializeObject(json);
                            dgTasks.DataSource = items.tasks;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
                }
            }

And convert grid data into json file.

Tasks tasks = new Tasks();
            tasks.tasks = (List)dgTasks.DataSource;
            
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            saveFileDialog1.InitialDirectory = @"C:\";
            saveFileDialog1.Filter = "JSON Image|*.json";
            saveFileDialog1.Title = "Save a JSON File";

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                File.WriteAllText(saveFileDialog1.FileName, JsonConvert.SerializeObject(tasks));
            }

Please download the project and use it in your projects. You have to add exception handling into this project.

How to extend c# ArrayList class

Sometimes we want to extend generic classes in c#. Here i have extended ArrayList in c# and overrided remove functions. I have also added Events to this class and if anyone interested you can go to my GitHub account and check.

Here is the extended class

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AnimalList
{

    // A delegate type for hooking up change notifications.
    //public delegate void MyAnimals_AnimalRemoved(MyAnimalList collection, Animal item);
    public delegate void MyAnimals_AnimalRemoved(object sender, AnimalListEventArgs e);

    /// <summary>
    /// MyAnimalList class only accept Animal types
    /// </summary>
    public class MyAnimalList : ArrayList
    {
        // An event that clients can use to be notified whenever the
        // elements of the list change.
        public event MyAnimals_AnimalRemoved AnimalRemoved;

        // Invoke the Changed event; called whenever list changes
        protected virtual void OnChanged(object sender, AnimalListEventArgs e) 
         {
             if (AnimalRemoved != null)
                 AnimalRemoved(this, e);
         }

         // Override some of the methods that can change the list;
         // invoke event after each
         public void Remove(int value)
         {
             MyAnimalList list = this;
             if (value > list.Count)
             {
                 MessageBox.Show(value+" is not a valid index", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                 return;
             }
             AnimalListEventArgs args = new AnimalListEventArgs((Animal)list[value]);
             OnChanged(this, args);
             base.Remove(value);
         }

         // Override some of the methods that can change the list;
         // invoke event after each
         public override void RemoveRange(int from,int to)
         {
             ArrayList list = this.GetRange(from, to);
             foreach(var animal in list)
             {
                 OnChanged(this, new AnimalListEventArgs((Animal)list[list.IndexOf(animal)]));
             }
             base.RemoveRange(from,to);
         }

         // Override some of the methods that can change the list;
         // invoke event after each
         public override void RemoveAt(int value)
         {
             MyAnimalList list = this;
             OnChanged(this, new AnimalListEventArgs((Animal)list[value]));
             base.RemoveAt(value);
         }

        /// <summary>
        /// Override + operator 
        /// </summary>
        /// <param name="list"></param>
        /// <param name="animal"></param>
        /// <returns></returns>
        public static MyAnimalList operator +(MyAnimalList list,Animal animal)
        {
            list.Add(animal);
            return list;
        }

        public new void Add(object value)
        {
            Type t = value.GetType();
            if (t.Equals(typeof(Animal)))
            {
                 base.Add((Animal)value);
            }
            else
            {
                MessageBox.Show("Only Animal type objects can be added to the MyAnimalList collection", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
           
        }
    }
}

And also i have extended EventArgs class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AnimalList
{
   public class AnimalListEventArgs:EventArgs
    {
       private readonly Animal animal;

       public AnimalListEventArgs(Animal animal)
       {
            this.animal = animal;
       }

       public Animal Animal
        {
            get { return this.animal; }
        }
    }
}

Here is my program class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AnimalList
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("||-- Starting animal program -- ||");

            MyAnimalList MyAnimals = new MyAnimalList();
            MyAnimals.AnimalRemoved += new MyAnimals_AnimalRemoved(ListChanged);

            MyAnimals.Add(new Animal(AnimalType.Amphibian, "Frog"));
            MyAnimals.Add(new Animal(AnimalType.Bird, "Eagle"));
            MyAnimals.Add(new Animal(AnimalType.Fish, "Bass"));

            MyAnimals += new Animal(AnimalType.Invertebrate, "Worm");
            MyAnimals += new Animal(AnimalType.Mammal, "Lion");
            MyAnimals += new Animal(AnimalType.Reptile, "Snake");

            MyAnimals.Add("dog");

            MyAnimals.Remove(5);
            MyAnimals.RemoveAt(3);
            MyAnimals.RemoveRange(1, 2);
            MyAnimals.Remove(5);

            foreach (Animal animal in MyAnimals)
            {
                MessageBox.Show("You still have a " + animal.AnimalName + " (" + animal.AnimalType + ")", "CS559 - Assignment 2", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }

        // This will be called whenever the list changes.
        private static void ListChanged(object sender, AnimalListEventArgs e)
        {
            MessageBox.Show(e.Animal.AnimalName +" was removed from the list.", e.Animal.AnimalType+" Removed", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}

How to read excel file using c#

Today I am going to show you how read excel file using c# and create folders based on excel file. Sometimes we may want to create many folders/sub folders based on business requirement and copy files into respective directory. So I am going to show how to do this using c# .net language. For this project i am using

  • Microsoft Visual Studio 2013
  • .net framework 4.5
  • ExcelDataReader library ( You can find it here)
  • Sample excel file which contain sample data set

Here is my project structure.

structure
Project Structure

Sample output

sample_output_parent
Parent folders
sample_output_child
Child folders

I have created sample console application to perform this task. I haven’t add exception handling for this code and feel free to optimize code and use it.

using Excel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FolderProject
{
    /// <summary>
    /// Author : Damith Wanninayake
    /// Excel 4.5 library url:https://github.com/ExcelDataReader/ExcelDataReader
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            FileStream stream = File.Open(ConfigurationManager.AppSettings["sourceFile"], FileMode.Open, FileAccess.Read);
            string basePath = ConfigurationManager.AppSettings["basePath"];

            // Reading from a OpenXml Excel file (2007 format; *.xlsx)
            IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);

            // DataSet - Create column names from first row
            excelReader.IsFirstRowAsColumnNames = true;
            DataSet result = excelReader.AsDataSet();

            // Getting distinct values
            var distinctValues = result.Tables[0].AsEnumerable()
                        .Select(row => new
                        {
                            Mem = row.Field<double>("Mem#"),

You can find the completed project which contains excel file in here. Please note that i am not the author of the excel file.