Press "Enter" to skip to content

Addendum JSON e la serializzazione delle Enumerazioni

Oggi, generando una classe per filtrare dati in una chiamata SQL, ho affrontato un piccolo problema sempre legato alle enumerazioni e al JSON

In questo Filtro, ho una property che è una lista di valori enumerati così da poter filtrare più tipi di oggetto.

Se vi ricordate l’enum dello scorso post: 

public enum Fruits
{
	NotSet,
	Apples,
	Oranges,
	Strawberries,
	Lemons,
	RedBerries,
	BlueBerries
}

Se volessi filtrare dei record su uno o più elementi dell’enumerazione, lo posso fare utilizzando una Collection di Fruits:

public List<Fruits> FruitTypes
{
   get; private set;
}

Se volessi che in una serializzazione JSON la lista mostrasse i nomi degli elementi e non i valori numerici come si fa? Molto Semplicemente si inserisce l’attributo di conversione dell’enumerazione in cima all’enumerazione stessa. Questo ci permetterà probabilmente di non dover mettere l’attributo sulle singole property del tipo enumerato.

[JsonConverter(typeof(StringEnumConverter))]
public enum Fruits
{
	NotSet,
	Apples,
	Oranges,
	Strawberries,
	Lemons,
	RedBerries,
	BlueBerries
}

Facendo questo, l’output di un oggetto FriendlyFruit con una lista di Fruit è il seguente


{
  "Name": "ListaDiFrutti",
  "Color": "Pink",
  "Type": "NotSet",
  "FruitList": [
    "Oranges",
    "Lemons",
    "Strawberries"
  ]
}

Come presumevo, aggiungere l’attributo all’enumerazione fa funzionare correttamente anche le property che non hanno l’attributo, nel nostro esempio dell’articolo prececente la classe StandardFruit.

** Standard Json Fruit **
{
  "Name": "Arancia",
  "Color": "Arancione",
  "Type": "Oranges"
}

Che nella versione precedente del test produceva il numero ora produce il nome.
Vi incollo il codice completo con la modifica inserita per questa dimostrazione.

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Conv = Newtonsoft.Json.Converters;
namespace EnumJson
{
	[JsonConverter(typeof(Conv.StringEnumConverter))]
	public enum Fruits
	{
		NotSet,
		Apples,
		Oranges,
		Strawberries,
		Lemons,
		RedBerries,
		BlueBerries

	}

	class Program
	{
		static void Main(string[] args)
		{
			//Let's produce two fruits
			StandardFruit standardFruit = new StandardFruit()
			{
				Name = "Arancia",
				Color = "Arancione",
				Type = Fruits.Oranges
			};

			FriendlyFruit friendlyFruit = new FriendlyFruit()
			{
				Name = "Mirtillo",
				Color = "Blu Scuro",
				Type = Fruits.BlueBerries
			};

			string standardJSON = standardFruit.ToJson(true);
			Console.WriteLine("** Standard Json Fruit **");
			Console.WriteLine(standardJSON);
			Console.WriteLine(new string('-', 80));

			string friendlyJSON = friendlyFruit.ToJson(true);
			Console.WriteLine("** Friendly Json Fruit **");
			Console.WriteLine(friendlyJSON);
			Console.WriteLine(new string('-', 80));

			standardFruit = StandardFruit.FromJson(friendlyJSON);
			friendlyFruit = FriendlyFruit.FromJson(standardJSON);
			Console.WriteLine("** Exchange of data before deserializing **");

			standardJSON = standardFruit.ToJson(true);
			Console.WriteLine("** Standard Json Fruit **");
			Console.WriteLine(standardJSON);
			Console.WriteLine(new string('-', 80));

			friendlyJSON = friendlyFruit.ToJson(true);
			Console.WriteLine("** Friendly Json Fruit **");
			Console.WriteLine(friendlyJSON);
			Console.WriteLine(new string('-', 80));

			Console.WriteLine("** Looks like Newtonsoft is automatically converting the enumeration, Clever!!! **");

			Console.WriteLine("** Lista di frutti con tipologie **");

			List<FriendlyFruit> fruttivari = new List<FriendlyFruit>();
			fruttivari.Add( new FriendlyFruit() { Color = "Orange", Name = "Albicocca", Type = Fruits.NotSet });
			fruttivari.Add( new FriendlyFruit() { Color = "Green", Name = "Granny Smith", Type = Fruits.Apples });
			fruttivari.Add( new FriendlyFruit() { Color = "Yellow", Name = "Golden", Type = Fruits.Apples });
			fruttivari.Add( new FriendlyFruit() { Color = "Indigo", Name = "Susina", Type = Fruits.NotSet });
			fruttivari.Add( new FriendlyFruit() { Color = "Orange", Name = "Mandarino", Type = Fruits.Oranges });
			fruttivari.Add( new FriendlyFruit() { Color = "Orange", Name = "Washington Navel", Type = Fruits.Oranges });
			fruttivari.Add( new FriendlyFruit() { Color = "Red and Green", Name = "Fuji", Type = Fruits.Apples });
			fruttivari.Add( new FriendlyFruit() { Color = "Red", Name = "Mirtilli rossi", Type = Fruits.RedBerries });
			fruttivari.Add( new FriendlyFruit() { Color = "Indigo", Name = "Mirtilli", Type = Fruits.BlueBerries });
			List<Fruits> tanti = new List<Fruits>();
			tanti.Add(Fruits.Oranges);
			tanti.Add(Fruits.Lemons);
			tanti.Add(Fruits.Strawberries);
			fruttivari.Add( new FriendlyFruit() { Color = "Pink", Name = "ListaDiFrutti", Type = Fruits.NotSet, FruitList=tanti });

			FruitCycle(fruttivari);
			Console.WriteLine("** Premi enter per terminare **");
			Console.ReadLine();

		}


		private static void FruitCycle( List<FriendlyFruit> fruits)
		{

			foreach (FriendlyFruit fruit in fruits)
			{
				switch (fruit.Type)
				{
					case Fruits.Apples:
						Console.WriteLine("This is an apple");
						Console.WriteLine(fruit.ToJson(true));
						break;
					case Fruits.Oranges:
						Console.WriteLine("This is an orange");
						Console.WriteLine(fruit.ToJson(true));
						break;
					case Fruits.Strawberries:
						Console.WriteLine("This is a strawberry");
						Console.WriteLine(fruit.ToJson(true));
						break;
					case Fruits.Lemons:
						Console.WriteLine("This is a Lemon");
						Console.WriteLine(fruit.ToJson(true));
						break;
					case Fruits.BlueBerries:
						Console.WriteLine("This is a blueberry");
						Console.WriteLine(fruit.ToJson(true));
						break;
					case Fruits.RedBerries:
						Console.WriteLine("This is a redberry");
						Console.WriteLine(fruit.ToJson(true));
						break;
					default:
						Console.WriteLine("Fruit type not set");
						Console.WriteLine(fruit.ToJson(true));
						break;
				}
			}


		}
	}

	class StandardFruit
	{
		private string mName;
		public string Name
		{
			get
			{
				return mName;
			}
			set
			{
				mName = value;
			}
		}

		private string mColor;

		public string Color
		{
			get
			{
				return mColor;
			}
			set
			{
				mColor = value;
			}
		}

		private Fruits mType;
		public Fruits Type
		{
			get
			{
				return mType;
			}
			set
			{
				mType = value;
			}
		}

		public string ToJson(bool indented)
		{
			Formatting formatting = Formatting.None;
			if (indented)
			{
				formatting = Formatting.Indented;
			}
			return JsonConvert.SerializeObject(this, formatting);
		}

		public static StandardFruit FromJson(string jsonData)
		{
			StandardFruit fruit = null;
			try
			{
				fruit = JsonConvert.DeserializeObject<StandardFruit>(jsonData);
			}
			catch (Exception)
			{
				fruit = null;
				//In caso di errore torniamo null
			}
			return fruit;
		}



	}

	class FriendlyFruit
	{
		public FriendlyFruit()
		{
			FruitList = new List<Fruits>();
		}

		private string mName;
		public string Name
		{
			get
			{
				return mName;
			}
			set
			{
				mName = value;
			}
		}

		private string mColor;

		public string Color
		{
			get
			{
				return mColor;
			}
			set
			{
				mColor = value;
			}
		}


		private Fruits mType;

		public Fruits Type
		{
			get
			{
				return mType;
			}
			set
			{
				mType = value;
			}
		}

		
		private List<Fruits> mFruitList;

	
		public List<Fruits> FruitList
		{
			get
			{
				return mFruitList;
			}
			set
			{
				mFruitList = value;
			}
		}




		public string ToJson(bool indented)
		{
			Formatting formatting = Formatting.None;
			if (indented)
			{
				formatting = Formatting.Indented;
			}
			return JsonConvert.SerializeObject(	this, formatting);
		}

		public static FriendlyFruit FromJson(string jsonData)
		{
			FriendlyFruit fruit = null;
			try
			{
				fruit = JsonConvert.DeserializeObject<FriendlyFruit>(jsonData);
			}
			catch (Exception)
			{
				fruit = null;
				//In caso di errore torniamo null
			}
			return fruit;
		}

	}
}