22

I have enum:

public enum Operation { /// <remarks/> [System.Xml.Serialization.XmlEnumAttribute("01")] Item01, /// <remarks/> [System.Xml.Serialization.XmlEnumAttribute("02")] Item02, /// <remarks/> [System.Xml.Serialization.XmlEnumAttribute("03")] Item03, /// <remarks/> [System.Xml.Serialization.XmlEnumAttribute("04")] Item04, } 

How I can get XmlEnumAttribute value?

I'm trying at that:

var res = Operation.Item1; var result = (res.GetType().GetField("Item01").GetCustomAttributes(typeof(XmlEnumAttribute), true)[0] as XmlEnumAttribute).Name; 

May be exists better method?

3 Answers 3

29

You could create an helper (static) class, with this extension method

public static string GetXmlEnumAttributeValueFromEnum<TEnum>(this TEnum value) where TEnum : struct, IConvertible { var enumType = typeof(TEnum); if (!enumType.IsEnum) return null;//or string.Empty, or throw exception var member = enumType.GetMember(value.ToString()).FirstOrDefault(); if (member == null) return null;//or string.Empty, or throw exception var attribute = member.GetCustomAttributes(false).OfType<XmlEnumAttribute>().FirstOrDefault(); if (attribute == null) return null;//or string.Empty, or throw exception return attribute.Name; } 

usage

var res = Operation.Item1; var result = res.GetXmlAttributeValueFromEnum(); 
Sign up to request clarification or add additional context in comments.

5 Comments

This may not work if the enum contains a member "Equals", "GetHashCode", "GetType" or "ToString". You should filter the result of enumType.GetMember by MemberType = Field.
@Rauhotz Indeed. But, I guess you'll admit, that would be would be a really (really) particular case (not to say a rather bad idea) !
I wrote that comment because i just had that rare case for an relational operator enum of a collegue.
This methodology worked for me to retrieve the value for an XmlEnumAttribute out of a third-party ServiceReference.
@Rauhotz Maybe add an answer which expands on this post to also include filtering out those terrible, terrible enumerator names?
10

You have to use Reflection to get the attribute value:

var value = Operation.Item02; var attributeValue = ((XmlEnumAttribute)typeof(Operation) .GetMember(value.ToString())[0] .GetCustomAttributes(typeof(XmlEnumAttribute), false)[0]) .Name; 

1 Comment

Thanks to all members
6

Thanks; this is useful to me. I'd like to extend Raphael's answer to a slightly more general scenario. If the enum code is generated from xsd by xsd.exe, not every enum will have the attribute. This may happen when you're using xsd enums to limit strings to a specific list of values, some of which have spaces and some of which don't. For example:

<xs:simpleType name="fooEnum"> <xs:restriction base="xs:string"> <xs:enumeration value="Foo Bar" /> <xs:enumeration value="Bar Foo" /> <xs:enumeration value="JustPlainFoo" /> </xs:restriction> </xs:simpleType> 

will emit the C# serialization code:

public enum fooEnum { /// <remarks/> [System.Xml.Serialization.XmlEnumAttribute("Foo Bar")] FooBar, /// <remarks/> [System.Xml.Serialization.XmlEnumAttribute("Bar Foo")] BarFoo, /// <remarks/> JustPlainFoo, } 

For this case, client code expecting "JustPlainFoo" will fail. My version of Raphael's answer is then as follows:

public static string XmlEnumToString<TEnum>(this TEnum value) where TEnum : struct, IConvertible { Type enumType = typeof(TEnum); if (!enumType.IsEnum) return null; MemberInfo member = enumType.GetMember(value.ToString()).FirstOrDefault(); if (member == null) return null; XmlEnumAttribute attribute = member.GetCustomAttributes(false).OfType<XmlEnumAttribute>().FirstOrDefault(); if (attribute == null) return member.Name; // Fallback to the member name when there's no attribute return attribute.Name; } 

Finally, I'll note that Rauhotz's commment won't apply to this case; the XmlEnumAttribute won't be there in the generated C# code and you'll just hit the fallback code.

4 Comments

I have some enums with similar values, and a class with variables of type of the enums. How can I set the enum data in the object, when my input string has a space?
@rohinMVP not sure what you mean here by "input string". If you're deserializing XML this should happen automatically. Are you trying (using my example) to convert "Bar Foo" to fooEnum.BarFoo in a general StringToXmlEnum function? This seems like an odd interface design, but you can certainly write a static method to do that for a single hard-coded type.
I have to serialize my form data into XML. So essentially it would be a String to Enum conversion. I have two Enums with multiple values having a space. Yes, I have to convert "Bar Foo" to fooEnum.BarFoo
@rohinMVP you should be able to just iterate the enum values to build a Dictionary<string, myEnumType> object and use that.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.