Format Enums as a Custom Name-Value Object List
Tags: csharp, dotnet
Published: 2020-07-26 16:30:41

I recently came across a scenario where I had to expose an enum property as a list of drop-down items to choose from. Typically when a user would select something from the drop-down and the form posted back to the server, the selection would be bound as a legit enum value.However the enum which we had defined was very system specific and not user savy.I could not just let the user select a particular enum value without giving out a description of the purpose it served.

There is little we can do when defining enums as they have to follow certain conventions and sometimes we are required to give them system specific values which might not be very descriptive to the end user. E.g. SYSTEM_ERROR_102 which might be some error only known to the developer.We cannot show this directly to the user and have to give some description about it.

In the example ahead, let us assume we have a simple form with two inputs - a textbox and a drop-down. The user has to enter a product name and assign it with a product type (select from the drop-down). At the back-end we are maintaining a Product enum as
```javascript
 public enum Product
 {
  Board,
  Table,
  Desk,
  Carpet
 }
```
For demo purpose let us assume the form is in Swedish and we need to show the product types in Swedish but at the same time when user selects a particular product type and the form is posted back it must be bound to one of the Product enum values . (Note the following is just one way to achieve it, there can be different ways to do it. Also your use case could be different, I have assumed this example for simplicity but the technique remains the same)

We start by defining our Product Enum as
```javascript
public enum Product
 {
 [Description("Bord")]
  Board,
 [Description("Stol")]
  Table,
 [Description("SkrivBord")]
  Desk,
 [Description("Matta")]
  Carpet
 }
```
Here we have made use of the DescriptionAttribute from the System.ComponentModel namespace.You can also go for your own custom attribute but since this is readily available we are good to go here. You can read about the Description Attribute [here](https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.descriptionattribute?view=netcore-3.1).
This Description Attribute will have whatever friendly name you want your Enum value to be associated with.

My back-end was an API and I wanted to return a list of anonymous object of type Name and Value. The name would be what shown as a selection in the list and the value would be bound to the selection. In our example here, the Name would be the Swedish counterpart and the value would be the actual enum value (Table,Desk,etc).
```javascript
 private dynamic FormatEnum(Enum value)
 {
 
 /*Since any valid (derived) Enum type could be passed to this function
 we need the exact Enum type passed to this func
 which we would require to process further.Here it would be "Product".
 */
 //type=Product;
 Type type = value.GetType();
  /*
Enums hold an integer value with the index starting from 0.
If we were to assign Product.Table and try to serialize it 
or save it in a db it would get stored as 1 
(Board=0, Table=1,Desk=2,Carpet=3).
Since we are working with dropdowns and want an user friendly interface, we are interested in the Name here.
Hence Enum.GetName(typeof(Product),Product.Table).
You could also do it with its index => Enum.GetName(typeof(Product),1)
 */
 //name = Table
 var name = Enum.GetName(type,value);
  if(name !=null)
 {//Now we are interested in the Description Attribute.
 /*The FieldInfo class belongs to the System.Reflection namespace and as
defined in MSDN, "Discovers the attributes of a field and provides access to field metadata."*/
	FieldInfo info = type.GetField(name);
	if(info !=null)
	{
	//Out of all the properties listed by the FieldInfo object we are interested in the  CustomAttributes which would give us access to the DescriptionAttribute
	 DescriptionAttribute descrp = (DescriptionAttribute) Attribute.GetCustomAttribute(info,typeof(DescriptionAttribute));
	 Console.WriteLine(descrp);
	if(descrp !=null)
	{
	   return new { Name =  descrp.Description , Value = name };
	}
	}
 }
 return null;
 }
```
The FieldInfo object would look like this and as shown above we are interested in the `CustomAttributes` property 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/s4nnj86j7t8tfjtv1hw9.JPG)

When we retrieve the DescriptionAttribute on an enum value we are interested in its "Description" property as that is what we set to begin with.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3upvn7fbdyrwtp41c3v0.JPG)

And then you could use this method like
```javascript
void Main()
{
	var products = Enum.GetValues(typeof(Product)).Cast<Enum>()
		.Select(e=> FormatEnum(e)).ToList();
	Console.WriteLine(products);
	
}


```

Output :
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gvvam1sthqzzm12z0v1v.JPG)