15

Is it possible to deserialize an enum from an int in c#. e.g. If I have the following class:

class Employee
{
   public string Name { get; set;}
   public int EmployeeTypeID { get; set;}
}

I can easily create this from XML

   <Employee>
       <Name>Joe Bloggs</Name>
       <EmployeeTypeID>1</EmployeeTypeID>
   </Employee>

using something like this:

Employee employee = (Employee)new XmlSerializer(typeof(Employee)).Deserialize(XmlReader);

With very little work involved, this allows me to use one generic service that I can use for all database objects by feeding a select command, connection string and a type in to and retrieve an array of objects without any need for further mapping. However I have come unstuck with enums. Supposing now instead of being an integer EmployeeType is an enum:

public enum EmployeeTypeEnum
{
   Admin = 1,
   Sales = 2
}

so my class becomes:

class Employee
{
   public string Name { get; set;}
   public EmployeeTypeEnum EmployeeTypeID { get; set;}
}

Can I use the same XML and make c# recognise that the int value of EmployeeTypeID in the xml should correspond with the int value of the enum? There are other questions similar out there, but none have a very satisfactory answer are quite old, and involve wholesale changes to code. I am hoping for a better solution...

As a possible separate note (and slightly in anticipation of some responses), is using enums for this a practise best avoided? Should I be using Key-Value pairs? I would always use Key-value pairs (or similar) if there were likely to be changes, but in this case EmployeeType is fixed and will never change.

GarethD
  • 68,045
  • 10
  • 83
  • 123
  • 1
    +1 - one of those questions I come across that I can't prove much use in but look forward to seeing the answer. – SkonJeet Mar 30 '12 at 14:05
  • 2
    Does http://stackoverflow.com/questions/506368/how-do-i-serialize-an-enum-value-as-an-int help? – Bridge Mar 30 '12 at 14:08
  • Or http://stackoverflow.com/questions/4250656/deserializing-enums ? – kerrubin Mar 30 '12 at 14:09
  • @Bridge Yes, that did help a lot, I was to busy searching for "deserialising enums" that I missed that article. – GarethD Mar 30 '12 at 14:23

3 Answers3

23

Theoretically (= I haven't tried it), adding the XmlEnum attribute to your enum values should do the trick:

public enum EmployeeTypeEnum 
{ 
    [XmlEnum("1")] Admin = 1, 
    [XmlEnum("2")] Sales = 2 
} 

This tells XmlSerializer that a value of EmployeeTypeEnum.Admin is to be serialized as the string 1 and vice-versa (which is what you need).

Regarding your side note: I don't see using enums here as a problem. If the values in the database are integers and have a fixed meaning, enums are a good solution and, in addition, serve as a documentation to the database values.

Heinzi
  • 167,459
  • 57
  • 363
  • 519
4

If you xml is in this format:

<Employee>
  <Name>Shiv</Name>
  <EmployeeTypeID>Sales</EmployeeTypeID>
</Employee>

It will work as is. If you decorate your enum with the XmlEnum attribute like so:

    public enum EmployeeTypeEnum
{
    [XmlEnum("1")]
    Admin = 1,
    [XmlEnum("2")]
    Sales = 2
}

Then you can use integer values in your xml file and they will be mapped to the enum automagically.

Personally, I prefer using enums in cases like this. Even if the items in the enum could increase over time, I prefer using enums. In fact such enums are code generated from the database, so in code you don't work with Ids (much more readable).

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Shiv Kumar
  • 9,599
  • 2
  • 36
  • 38
0

In xml file, Use named constant in stead of integer value. It will work just fine.

<Employee>
       <Name>Joe Bloggs</Name>
       <EmployeeTypeID>Admin</EmployeeTypeID>
</Employee>