Search code examples
c#.netwcfxsd

XmlEnumAttribute does not work in WCF request


I have an XSD file which contains the following sequence :

<xs:simpleType name="typeVersion">
    <xs:restriction base="xs:string">
        <xs:enumeration value="01.01.01"/>
    </xs:restriction>
</xs:simpleType>

I use the XSD tool to generate C# code from it. The sequence is translated to

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
public enum typeVersion {

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("01.01.01")]
    Item010101,
}

I use the generated code to create a request for a WCF service. The request contains an item of type typeVersion. The problem is that 01.01.01 in a Soap UI request xml will not deserialize properly. It throws an exception with the message : The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:request. The InnerException message was 'Invalid enum value '01.01.01' cannot be deserialized into type 'typeVersion'. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.'. Please see InnerException for more details. According to http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlenumattribute.aspx?cs-save-lang=1&cs-lang=csharp, the XmlEnumAttribute should be able to convert the specified string to the corresponding enum value. For curiosity I tried replacing 01.01.01 with Item010101, and the request is successfully deserialized.

How does this not work, even though msdn states clearly that the attribute should work? Is there any way around this, to make it work? Solutions that do not require the generated file to be edited are preferred. Thanks!


Solution

  • I just came across the same problem when setting up a WCF web service which needs to use the XmlSerializer. The solution was to avoid using OperationFormatUse.Encoded in the specification of the service and its operations:

    XmlSerializerFormat(Style = OperationFormatStyle.Rpc, Use = OperationFormatUse.Literal)
    

    Note that Literal is the default setting, so it can be omitted:

    XmlSerializerFormat(Style = OperationFormatStyle.Rpc)