Java – WCF Serialization problems with WSDL file created by Java tools

interopjavaserializationwcfwsdl

My team is tasked with getting several in-house developed .NET client applications to connect to some new Java web services. The Java web service is a third party, vendor supplied WSDL file that our team has a limited ability to modify/control…meaning we probably have the power to request our vendor to make slight tweaks to the WSDL, but major changes would probably be either unfeasible or difficult to request.

That said, we are attempting to utilize WCF/.NET 4.0 to generate the .NET proxy class files we need on the client side. The proxy client class file generation process executes without issues.

The problem is when we attempt to use the proxy class file in a client app. I have verified through the web trace tool, Fiddler, that the raw SOAP message request fails to get sent across the wire to the server.

The specific .NET exception message I get when attempting to call the web service method in question, looks like this:

System.InvalidOperationException was unhandled
Message=XmlSerializer attribute System.Xml.Serialization.XmlAttributeAttribute is not valid in baseLanguage. Only XmlElement, XmlArray, XmlArrayItem, XmlAnyAttribute and XmlAnyElement attributes are supported when IsWrapped is true.
Source=System.ServiceModel

When I examine the .NET autogenerated proxy class file, Reference.cs, I noticed that the request and response messages for my web service method looks something like this:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.MessageContractAttribute(WrapperName="QueryPBOT_MXWO_OS", WrapperNamespace="http://www.ibm.com/maximo", IsWrapped=true)]
public partial class QueryPBOT_MXWO_OSRequest {

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=0)]
    public ConsoleApplication7.wsMaximo.PBOT_MXWO_OSQueryType PBOT_MXWO_OSQuery;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=1)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string baseLanguage;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=2)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string transLanguage;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=3)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string messageID;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=4)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string maximoVersion;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=5)]
    [System.Xml.Serialization.XmlAttributeAttribute()]
    [System.ComponentModel.DefaultValueAttribute(false)]
    public bool uniqueResult;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=6)]
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="positiveInteger")]
    public string maxItems;

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.ibm.com/maximo", Order=7)]
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="integer")]
    [System.ComponentModel.DefaultValueAttribute("0")]
    public string rsStart;

    public QueryPBOT_MXWO_OSRequest() {
    }

    public QueryPBOT_MXWO_OSRequest(ConsoleApplication7.wsMaximo.PBOT_MXWO_OSQueryType PBOT_MXWO_OSQuery, string baseLanguage, string transLanguage, string messageID, string maximoVersion, bool uniqueResult, string maxItems, string rsStart) {
        this.PBOT_MXWO_OSQuery = PBOT_MXWO_OSQuery;
        this.baseLanguage = baseLanguage;
        this.transLanguage = transLanguage;
        this.messageID = messageID;
        this.maximoVersion = maximoVersion;
        this.uniqueResult = uniqueResult;
        this.maxItems = maxItems;
        this.rsStart = rsStart;
    }
}

I know that people reading this post will want to see the actual WSDL file we're trying to consume, but it is quite large, and I'm concerned the sheer size of it would make pinpointing the error quite difficult.

I'm hoping that the autogenerated client proxy file and the .NET exception will help someone recognize this WCF Serialization issue.

We've confirmed from our Java vendor that the style of WSDL they generate is doc-literal. After doing some research on the internet, it appears that WCF, by default. translates WSDL files with doc-literal wrapped, and that this may explain, at least in part, why we're seeing this WCF serialization issue with the WSDL file.

I've discovered, through trial and error, that the following attribute decorator in the proxy class file is the culprit behind the serialization issue:

[System.Xml.Serialization.XmlAttributeAttribute()]

If I comment out all instances of this attribute in the proxy class file and rerun my client app, the SOAP message successfully gets sent across the wire and I get a valid web service response come back from the server.

This fix is better than nothing, but I would very much prefer a solution that doesn't require myself or anyone on my team to constantly tweak these .NET autogenerated proxy class files.

I would like to know if there is something I can do, either through the various WCF tools or by modifying the WSDL file, that prevents that [System.Xml.Serialization.XmlAttributeAttribute()] from being applied to my request and response object properties?

Or at least a high level description of WHY we are seeing this serialization behavior in .NET with the Java WSDL file?

thanks in advance,
John

Best Answer

Use svcutil.exe utility with the /wrapped option on to generate proxy classes.

This will create slightly different classes then those created though Visual Studio in a way described by Ladislav Mrnka here. Resulting proxies should be free from the XmlAttribute issue when using on the client side.

Example:

svcutil /t:code wsdl.xml /out:wsdl.cs /serializer:XmlSerializer /wrapped