如何用WCF WsdlExporter生成与singleWsdl一致的可用WSDL?
解决WsdlExporter生成WSDL缺少复杂类型定义的问题
你遇到的核心问题是:默认情况下WsdlExporter只会导出服务契约和端点的元数据,但不会自动包含数据契约(比如你的CompositeType)的XML Schema定义,这就导致生成的WSDL缺失关键类型信息,SoapUI和WcfTestClient加载时自然会报错。
要生成和运行时singleWsdl完全一致的可用WSDL,你需要手动导出数据契约的Schema并整合到生成的元数据中,下面是修改后的完整代码:
WsdlExporter exporter = new WsdlExporter(); exporter.PolicyVersion = PolicyVersion.Policy15; // 获取服务契约 var myContract = ContractDescription.GetContract(typeof(IService1)); // 导出数据契约的XML Schema,确保复杂类型被包含 XsdDataContractExporter xsdExporter = new XsdDataContractExporter(exporter.GeneratedXmlSchemas); foreach (var operation in myContract.Operations) { // 遍历每个操作的消息,导出参数/返回值中的复杂类型 foreach (var message in operation.Messages) { if (message.Body.Parts.Count > 0) { foreach (var part in message.Body.Parts) { var dataType = part.Type; if (xsdExporter.CanExport(dataType)) { xsdExporter.Export(dataType); } } } } } // 导出服务契约和端点 exporter.ExportContract(myContract); exporter.ExportEndpoint(new ServiceEndpoint(myContract, new BasicHttpBinding(), new EndpointAddress("http://x.y.z/Service1.svc"))); // 生成完整的合并元数据(WSDL + Schema) string wsdl; using (var sw = new StringWriter()) { var metadataSet = exporter.GetGeneratedMetadata(); using (var xmlWriter = XmlWriter.Create(sw)) { metadataSet.WriteTo(xmlWriter); } wsdl = sw.ToString(); } return wsdl;
关键改动说明:
- 添加数据契约导出逻辑:通过
XsdDataContractExporter遍历服务契约中所有操作的消息部分,导出其中包含的复杂类型(比如CompositeType)的XML Schema,并将这些Schema添加到WsdlExporter的Schema集合中。 - 使用MetadataSet输出:替换直接写入单个
GeneratedWsdlDocuments的方式,改用exporter.GetGeneratedMetadata()获取包含WSDL和所有关联Schema的完整元数据集,这样生成的内容和运行时的singleWsdl结构完全一致——所有依赖的Schema都会被内联或引用到最终的WSDL文档中。
这样修改后,生成的WSDL就会包含CompositeType的完整定义,能够被SoapUI和WcfTestClient正常加载使用。
内容的提问来源于stack exchange,提问作者Martin Mulder
相关产品推荐
相关产品推荐

