Interoperability between .NET, Java and legacy stacks

Most cross-vendor failures come from a handful of known divergences in encoding, dates, nulls and empty collections.

The known divergences

AreaThe disagreementFix
Encoding styleOne side emits RPC/encodedForce document/literal wrapped
Empty arrayOne emits no element, the other an empty elementAgree on minOccurs=0 and treat both as empty
Null valuexsi:nil versus an omitted elementUse nillable="true" consistently, or omit consistently
Date and timeLocal time without an offsetRequire an offset in the schema pattern
Decimal roundingDifferent default scale in serialisationPin the scale with xs:fractionDigits
Boolean1 versus trueBoth are valid; make the parser accept both
Namespace prefixns1: versus tns:Never compare XML as text; parse it
Header orderingDifferent order of header blocksCompare headers by name, not position
WS-Security canonicalisationInclusive versus exclusivePin exclusive canonicalisation with comments off
<!-- A conformance harness: assert on the parsed tree, never on the string -->
<!-- tools/compare.xsl -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:template match="/">
    <xsl:for-each select="//*">
      <xsl:value-of select="local-name()"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="normalize-space(.)"/>
      <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
# Normalise both responses and diff them
xsltproc tools/compare.xsl java-response.xml > java.txt
xsltproc tools/compare.xsl dotnet-response.xml > dotnet.txt
diff -u java.txt dotnet.txt

Running a cross-stack conformance suite

  • Generate clients for all stacks from the same WSDL revision, and record which revision each was built from.
  • Run a shared request fixture set through every client and diff the normalised responses.
  • Include the negative cases: a missing optional field, a maximum-length string, a decimal with a trailing zero, a timestamp at midnight UTC, and a deliberate fault.
  • Test with the oldest runtime you still support. Modern stacks are more forgiving than the legacy partner you will actually meet.
  • Review the WS-I Basic Profile for the rules your platform violates by default, then disable those violations explicitly.
  • Version the WSDL and the harness together so a contract change fails the suite rather than a production partner.
⚠️
Do not compare SOAP responses as strings. Namespace prefix choice, attribute order, self-closing tags and insignificant whitespace all vary legitimately between stacks, and a string diff will report dozens of failures that are not defects.

FAQ

Can I ever compare responses byte for byte?
Only for signature verification, and then both sides must canonicalise identically by agreement. For functional comparison, parse and normalise.
Why does the .NET client reject a valid Java response?
Usually a schema element the .NET proxy generated as non-nillable, or an empty element where the client expects an omitted one. Compare the generated proxy's schema against the WSDL.

XML Schema and data types in messages Attachments and binary data: MTOM and SwA

Last refreshed 2026-09-18.