Web サービスからの SOAP 応答を逆シリアル化できる C# .NET アプリを作成しようとしています。Web サービス (ここでは「Wibble」と呼ばれます) には WSDL (Grrrrrrr) がありません。中間クラスを生成するために使用できると思われる完全なサンプル応答のコピーがありますが、さまざまな方法を試しても、応答から適切なオブジェクトを取得できません。
応答の最初の数行は次のようになります。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:inspectResponse xmlns:ns1="ProjectService" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<inspectReturn href="#id0"/>
</ns1:inspectResponse>
<multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="Wibble" id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:Project">
<category xsi:type="ns2:Category" xsi:nil="true"/>
<classId xsi:type="xsd:long">1000000</classId>
[...]
</multiRef>
<multiRef xmlns:ns3="Wibble" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" id="id3" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns3:ProjectData">
<author xsi:type="ns3:User" xsi:nil="true" />
<authorUserId xsi:type="xsd:long">5289027</authorUserId>
<classId xsi:type="xsd:long">0</classId>
<comments xsi:type="xsd:string">Some comments.</comments>
[...]
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
等...
まず、次のように使用しようとするとSoapFormatter
:
var formatter = new SoapFormatter();
var blah = formatter.Deserialize(memstream);
return blah.ToString();
私は得るSerializationException
:Parse Error, no assembly associated with Xml key ns1 inspectResponse
inspectResponse
したがって、最初の要素をマップできるというクラスが欠落していると思います。そこでxsd.exe
、XML ファイルからいくつかの xsds を解読して生成します。ここから、52KB の C# クラスを生成します。このクラスには、XML ファイルがマップできるすべてのクラスが含まれていると推測されますが、一連のコードが含まれています。それを含めて、上記のコードを再実行すると、まったく同じエラーが発生します。
それで、自動生成されたクラスができたので、XmlSerializer
オブジェクトを使用して、その方法で逆シリアル化を試みることができるという考えが得られました。私はこれを書きます:
var ss = new XmlSerializer(typeof(Classes.Envelope));
object blah;
using (var xr = XmlReader.Create(new StringReader(response)))
{
ss.Deserialize(xr);
blah = ss.Deserialize(xr);
}
return blah.ToString();
今回は新しいものを取得しますInvalidOperationException
:There is an error in XML document (2, 356). ---> System.InvalidOperationException: The specified type was not recognized: name='Project', namespace='Wibble', at <multiRef xmlns=''>.
自動生成されたコードにはProject
クラスが含まれていますが、multiRef
クラスは含まれていません。Project
クラスが存在しないため、おそらくバーフィングです。プレースホルダーを作成してみます:
[Serializable]
[XmlType(TypeName = "Project", Namespace = "Wibble")]
public class Project
{
}
しかし、それは効果がありません。
私はここでマークから外れていますか、それとも小さなものを見逃しているだけですか? multiRef
さまざまなタイプの複数の要素を含むかなり複雑な XML 応答であることは理解SoapSerializer
できますが、 がそれを使って何かできるはずだと思っていました。