Java, .NET, Web Services and Enums

While working on getting a Java Web service and a .NET Web service client to talk to one another, I ran into an interesting situation. The problem had to do with the WSDL being produced by the Java service. Actually, the entire process involved the following steps:

  • An interface written in C# was used to generate a WSDL file.
  • That WSDL file was imported into JDeveloper and a web service was created
  • The WSDL file exposed by the JDeveloper web service was used (through the wsdl.exe tool) to create a proxy class to be used by a .NET client.

The problem was caused by enumerations being used in the interface. The WSDL file generated using the C# interface included defined a separate type (with a base of string) for each enumeration and then restricted the string values for that type. However, the WSDL file exposed by the JDev web service expected that the enumerated parameters would be of type string. Not the restricted, created type that C# wants to send. The resulting type mismatch caused the requests from the .NET client to the Java web service to be rejected with an ‘unknown type’ message.

The solution, while admittedly a hack, demonstrations a little discussed features of enumerations. Consider property called Status that is declared as an enumerated type of CallStatus. I added a field called StatusString defined as below and decorated the Status property with a SoapIgnore attribute as follows:

[SoapElement(“Status”)]
public string StatusString
{
   get { return Enum.GetName(typeof(CallStatus), status); }
   set { status = (CallStatus)Enum.Parse(typeof(CallStatus), value); }
}

[SoapIgnore()]
public CallStatus Status
{ … }

The SoapIgnore attribute hides the ‘real’ Status property from the SOAP serialization process. Instead the StatusString property, which is used to convert enumerated values to and from a string, is marked as being the ‘Status’ from the perspective of SOAP serialization. One item that may or may not be a problem is that the assigned value of StatusString could be null. This isn’t considered as part of this example, as the Web service was under a compulsion to return a valid value. But if the field is nilable, then you would need to code for that in the StatusString setter.