Get XmlEnumAttribute from enum

15,958

Solution 1

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();

Solution 2

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;

Solution 3

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.

Share:
15,958

Related videos on Youtube

zrabzdn
Author by

zrabzdn

Updated on September 14, 2022

Comments

  • zrabzdn
    zrabzdn over 1 year

    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?

  • zrabzdn
    zrabzdn over 10 years
    Thanks to all members
  • Rauhotz
    Rauhotz almost 9 years
    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.
  • Raphaël Althaus
    Raphaël Althaus almost 9 years
    @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) !
  • Rauhotz
    Rauhotz almost 9 years
    I wrote that comment because i just had that rare case for an relational operator enum of a collegue.
  • Russ
    Russ almost 8 years
    This methodology worked for me to retrieve the value for an XmlEnumAttribute out of a third-party ServiceReference.
  • Russ
    Russ almost 8 years
    @Rauhotz Maybe add an answer which expands on this post to also include filtering out those terrible, terrible enumerator names?
  • entryton
    entryton over 3 years
    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?
  • Eric Hirst
    Eric Hirst over 3 years
    @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.
  • entryton
    entryton over 3 years
    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
  • Eric Hirst
    Eric Hirst over 3 years
    @rohinMVP you should be able to just iterate the enum values to build a Dictionary<string, myEnumType> object and use that.