【问题标题】:Deserialize SOAP response from webservice without WSDL反序列化来自没有 WSDL 的 web 服务的 SOAP 响应
【发布时间】:2012-09-04 11:43:36
【问题描述】:

我正在尝试编写一个可以反序列化来自 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>

等等……

首先,如果我尝试像这样使用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 文件中生成了一些 xsd。从这里,我生成了一个 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). ---&gt; System.InvalidOperationException: The specified type was not recognized: name='Project', namespace='Wibble', at &lt;multiRef xmlns=''&gt;.

自动生成的代码不包含Project 类,尽管它包含multiRef 类。大概是因为不存在 Project 类,所以它很讨厌。我尝试创建一个占位符:

[Serializable]
[XmlType(TypeName = "Project", Namespace = "Wibble")]
public class Project
{
}

但这没有任何效果。

我在这里是不是太离谱了,还是我只是漏掉了一些小东西?我很欣赏这是一个相当复杂的 XML 响应,其中包含多个不同类型的 multiRef 元素,但我原以为 SoapSerializer 应该能够用它做点什么。

【问题讨论】:

标签: c# .net xml soap deserialization


【解决方案1】:

好的,为什么不尝试将响应加载到 XMLDomDocument 中并使用 XPATH 表达式或 XSLT 来查询您感兴趣的节点。然后自定义映射器类可以将节点属性映射到您的 POCO 类中。

只是一个想法和一个糟糕的解决方法,以防您找不到其他任何东西,但我很惊讶 SOAP 返回消息没有 WSDL。这是公共服务吗。

您是否也尝试在服务 URL 的末尾附加 ?WSDL 并查看会发生什么。

【讨论】:

  • 我认为这可能是我的后备方案。我与服务开发人员就缺少 WSDL 进行了多次争论。就是没有。不过,他们正在“考虑”开发一款。
猜你喜欢
  • 1970-01-01
  • 2012-07-29
  • 2011-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多