无法使用SVCUTIL创建带有datacontract的“ShareLibrary”

时间:2012-05-27 08:34:08

标签: xsd datacontractserializer datacontract xmlserializer svcutil.exe

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

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

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

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

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

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

  

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

     

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

     

如果您使用/ dataContractOnly选项导入数据合同   类型并且收到此错误消息,请考虑使用xsd.exe   代替。 xsd.exe生成的类型可以在Windows中使用   申请后的交流基金会   服务合同上的XmlSerializerFormatAttribute属性。   或者,考虑使用/ importXmlTypes选项导入   这些类型作为与DataContractFormatAttribute一起使用的XML类型   属于您的服务合同。

1 个答案:

答案 0 :(得分:1)

在我们的支持活动中,我们经常看到像你这样的请求,足以引出模式。如果没有看到实际的XSD和WSDL,很难(对任何人来说)说你是否遇到了产品错误或其他问题。

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

在.NET上,我对你的案例的解决方案是使用基于WSDL规范支持的小组件来进行组件化创作。假设您有两个服务的AbcXyz的WSDL。我像这样构建一个“包装器”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需要相同,则{urn:paschidev-com:xsd:common:1}something必须来自两个WSDL的相同源URI。

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

有时,即使我让XSD正确,svcutil或xsd仍然可能会窒息;如果发生这种情况,它就会与包装器无关;即使没有这个包装器,它也会表现出来。这意味着确保在任何重构发生之前,每个单独的WSDL都可以自行运行,这总是一个好主意。