soap-errorswcfxml

The formatter threw an exception while trying to deserialize the message の原因と対処法

SOAPless Team3 min read

このエラーは WCF 側でよく出るもので、意味としては「受け取った XML body が契約どおりではなかった」です。

The formatter threw an exception while trying to deserialize the message

さらに詳細で次のような文言が出ることもあります。

There was an error while trying to deserialize parameter

この場合、失敗している parameter を起点に見るのが最短です。

主な原因

  • wrapper 要素名が違う
  • namespace URI が違う
  • primitive のはずが object になっている
  • 配列と単体要素の形がずれている
  • optional / nillable の扱いが契約と違う

wrapper mismatch の例

期待されている形:

<tns:GetCustomer xmlns:tns="http://example.com/contracts">
  <tns:id>42</tns:id>
</tns:GetCustomer>

実際に送っている形:

<GetCustomerRequest xmlns="http://example.com/contracts">
  <id>42</id>
</GetCustomerRequest>

これだけでも formatter exception は起こります。

切り分け方

最小リクエストから始めて、1 フィールドずつ足してください。

curl -s https://example.com/service.svc?wsdl -o service.wsdl

次を重点的に見ます。

  1. operation 要素名
  2. parameter の順序
  3. 子要素の namespace
  4. 配列か単体か

SoapUI では通るのにアプリでは落ちる場合、SoapUI の raw request と diff を取るのが最短です。

配列と scalar のズレ

JSON から XML を手で組み立てる時に起きがちです。

期待:

<tns:tags>
  <tns:string>red</tns:string>
  <tns:string>blue</tns:string>
</tns:tags>

実際:

<tns:tags>red</tns:tags>

見た目は近くても契約としては別物です。

shell ベースの確認

curl -v https://example.com/service.svc \
  -H 'Content-Type: text/xml; charset=utf-8' \
  --data @request.xml

コードを触る前に raw XML で再現させると、ライブラリ由来のノイズが消えます。

このエラーが複数のジョブやスクリプトで繰り返し出るなら、XML の責務をアプリごとに持たせない構成に寄せた方が再発を減らせます。