我正在尝试编写一个可以反序列化来自 Web 服务的 SOAP 响应的 C# .NET 应用程序。Web 服务(此处称为“Wibble”)没有 WSDL (Grrrrrrrr)。我有一个完整的示例响应的副本,我相信我可以用它来生成中间类,但是尽管尝试了许多不同的方法,但我无法从响应中得到一个理智的对象。
响应的前几行如下所示:
<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>
ETC...
首先,如果我尝试使用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
{
}
但这没有任何效果。
我在这里偏离了标记,还是我只是错过了一些小东西?我很欣赏这是一个相当复杂的 XML 响应,其中multiRef
包含所有不同类型的多个元素,但我原以为SoapSerializer
应该能够用它做点什么。