3

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();

私は得るSerializationExceptionParse 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();

今回は新しいものを取得しますInvalidOperationExceptionThere 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できますが、 がそれを使って何かできるはずだと思っていました。

4

1 に答える 1

1

では、応答を XMLDomDocument にロードして、XPATH 式または XSLT を使用して関心のあるノードを照会してみませんか。次に、カスタム マッパー クラスがノード属性を POCO クラスにマップできます。

他に何も見つからない場合の単なる考えと悪い回避策ですが、SOAP の戻りメッセージに WSDL がないことに驚いています。これは公共サービスですか。

また、サービス URL の末尾に ?WSDL を追加して、何が起こるかを確認しましたか。

于 2012-09-04T13:59:26.980 に答える