2

案例:我有一组 xsd 文件,它们定义了 WSDL 定义中使用的常见类型(Header、ApplicationError)。每个 web 服务在服务特定类型旁边输入一个或多个这些共享类型。

在为服务生成代理时,我不断地为每个服务代理获取这些共享类型的副本,因此我打算将它们放在共享库中并使用 /reference 来包含这些类型。我无法让它工作。

首先,生成代理并包含所有 *.xsd 工作正常,并生成合同。然后使用带有 /dconly 参数的每个 xsd 的 svcutil 不起作用。/XmlSerializer 都作为 /DataContractSerializer。只有 /importXmlType(或 xsd.exe)有效。

然后,如果我将它们放在一个类项目中,添加生成的代码,编译并将其用于 /reference 参数,我仍然会为这些类型生成代码。

即使我使用为代理生成的类,svcutil 仍然无法识别它们。

任何人都有这种模式的经验,也许遇到过同样的问题?

XmlSerializer 作为 DataContractSerializer svcutil /dconly /ser:XmlSerializer ApplicieFout-v0200-b03.xsd 的错误消息

错误:无法导入命名空间“http://schemas.customer.nl/ApplicatieFout-v0200”中的“ApplicatieFout”。元素“FoutCode”上的表单必须是合格的。要么更改架构,以便类型可以映射到数据协定类型,要么使用 ImportXmlType 或使用不同的序列化程序。

如果您使用 /dataContractOnly 选项导入数据合同类型并收到此错误消息,请考虑改用 xsd.exe。在您的服务合同上应用 XmlSerializerFormatAttribute 属性后,可以在 Windows Communication Foundation 中使用由 xsd.exe 生成的类型。或者,考虑使用 /importXmlTypes 选项将这些类型导入为 XML 类型,以便与服务合同上的 DataContractFormatAttribute 属性一起使用。

4

1 回答 1

1

在我们的支持活动中,我们经常看到像您这样的请求,足以说明一种模式。在没有看到实际的 XSD 和 WSDL 的情况下,(任何人)都很难说您是否遇到了产品错误或其他问题。

然而,多年来我学到的是,处理 XSD 到代码绑定的一般工具总是有限的。要解决这些限制,解决方案是从仔细规划 XSD 内容以及 WSDL 必须如何使用该内容开始。如果我控制生成 WSDL 和 XSD 的过程会更容易;当我“继承”或“采用”他人的时,我会应用自己的重构。

在 .NET 上,我对您的情况的解决方案是使用基于 WSDL 对组件化创作的规范支持的小技巧。假设您有两个服务的 WSDL,Abc并且Xyz. 我像这样构建一个“包装器”WSDL:

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    targetNamespace="http://services.paschidev.com/wrapper/usecase_a/1/" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:import namespace="http://services.paschidev.com/service_abc/1/" location="AbcService.wsdl" />
  <wsdl:import namespace="http://services.paschidev.com/service_xyz/1/" location="XyzService.wsdl" />
  <wsdl:types />
</wsdl:definitions>

通过您的实用程序提供此内容(使用 Visual Studio 2010 成功测试,添加服务引用命令),您就完成了。

细则...为了使所有这些都以高成功率工作,您希望组合的所有 WSDL 都必须遵循以下规则:通用 XSD 必须来自通用源。

如果服务Abc需要{urn:paschidev-com:xsd:common:1}somethingXyz需要相同,则 a{urn:paschidev-com:xsd:common:1}something必须来自两个 WSDL 的相同源 URI。

测试对我来说相当简单:我使用QTAssistant的(我与它相关联)通过将其指向包装器WSDL来提取 XSDs命令。出现提示时,我让它创建一个 XSR 项目;如果从生成的 XSD 创建的集合编译良好,则意味着没有重复的 XSD 定义。如果编译给出“已经定义”的错误,报告会告诉我哪个 XSD 组件是重复的,即来自两个或多个不同的源 Uris。我重构每个组件以保留一个源 uri;然后再试一次。

有时,即使我得到了正确的 XSD,svcutil 或 xsd 仍可能会阻塞;如果发生这种情况,那就是与包装无关的东西;即使没有这个包装器,它也会表现出来。这意味着确保在进行任何重构之前,每个单独的 WSDL 都可以单独运行良好,这始终是一个好主意。

于 2012-05-27T13:36:30.837 回答