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
| Area | The disagreement | Fix |
|---|---|---|
| Encoding style | One side emits RPC/encoded | Force document/literal wrapped |
| Empty array | One emits no element, the other an empty element | Agree on minOccurs=0 and treat both as empty |
| Null value | xsi:nil versus an omitted element | Use nillable="true" consistently, or omit consistently |
| Date and time | Local time without an offset | Require an offset in the schema pattern |
| Decimal rounding | Different default scale in serialisation | Pin the scale with xs:fractionDigits |
| Boolean | 1 versus true | Both are valid; make the parser accept both |
| Namespace prefix | ns1: versus tns: | Never compare XML as text; parse it |
| Header ordering | Different order of header blocks | Compare headers by name, not position |
| WS-Security canonicalisation | Inclusive versus exclusive | Pin 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> </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.txtRunning 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.
Related
XML Schema and data types in messages Attachments and binary data: MTOM and SwA
Last refreshed 2026-09-18.