从WSDL生成C#类

8
我希望在ASP.NET Core 2.1中从wsdl url生成C#类。
WSDL url是:https://airarabia.isaaviations.com/webservices/services/AAResWebServices?wsdl 我使用了“Microsoft WCF Web Service Reference Provider”工具来生成C#类,但出现以下错误:
错误:未生成任何代码。如果您尝试生成客户端,则可能是因为元数据文档不包含任何有效的合同或服务,或因为所有合同/服务都被发现存在于/reference程序集中。请验证是否将所有元数据文档传递给了该工具。完成。
非常感谢您提供任何解决方案。

4
除非你曾经与英国政府数字服务和航空公司合作过,否则请立即停止点赞下降。航空公司是非常重要的,没有时间遵循既定标准。请记住保留原文意思,并尽可能使翻译通俗易懂。 - Panagiotis Kanavos
1
@Ahmad1334 航空公司在网络标准方面表现得有些草率。WSDL 可能是无效的。尝试使用 svcutil.exe 生成类。如果可以并且没有错误,您将知道这可能是 .NET Core 的 WCF 支持存在的问题。好消息是,您可以在 .NET Core 项目中重用生成的类。 - Panagiotis Kanavos
1
@Ahmad1334 如果 svcutil.exe 报错,可能是因为该航空公司不支持 SOAP 或 WS-* 标准。例如,Sabre 就不支持,而是使用 ebXML 代替 SOAP。其他服务,如 Farelogix,甚至不遵守自己的 XSDs。 - Panagiotis Kanavos
@Ahmad1334 哎呀,情况比我想象的还要糟糕。WSDL引用了OpenTravel模式,但没有提供链接。不过你可以使用svcutil.exe和一个http URL来生成代理类。 - Panagiotis Kanavos
你可以直接在MS Visual Studio中插入相应的服务引用!然后VS将根据你指定的命名空间为你创建CS类。 - peter70
显示剩余8条评论
2个回答

15

简短回答

打开开发命令提示符并运行以下命令以生成代理类:

svcutil http://airarabia.isaaviations.com/webservices/services/AAResWebServices?wsdl

注意我使用了http而不是https。服务器的证书会导致svcutil出现问题。将这些类复制到您的项目文件夹中。

从NuGet添加System.ServiceModel.Primitives到项目的依赖项中。由于ASP.NET Core不使用web.config文件,创建代理类时可能需要自己创建绑定,例如:

var binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
var address = new EndpointAddress("http://airarabia.isaaviations.com/webservices/services/AAResWebServices");
var client = new AAResWebServicesClient((Binding)binding, address);
在绑定中,使用BasicHttpsBinding,因为没有航空公司接受未加密的连接。Sabre要求TLS 1.2或更高版本。 说明 航空公司和GDS在遵循Web互操作标准方面并不太擅长。它们足够大,以至于如果有任何更改,旅行社就必须适应它们。一旦它们指定了它们的标准,它们也不会关心进行更改。
例如,OTA标准和Sabre的实现是在2003年使用ebXML创建的,这是一个未成为标准的SOAP替代提案。然后,他们使用了机制,这些机制并未成为后来的SOAP标准的一部分,在SOAP上使用ebXML。当WS-*标准被创建来修复混乱并确保互操作性时,他们甚至都没有费心去做。
您提供的WSDL类似于Sabre的WSDL。它使用OTA的一些操作,例如OTA_PING,并添加自定义操作。幸运的是,它不包含任何像匿名内部类型之类的工具破坏者。
您可以使用wsdl.exe创建ASMX代理,使用预2008 .NET堆栈。据我所知,这还没有移植到.NET Core。也许它是Windows兼容性包的一部分。毕竟,它是不兼容的,并且在10年前被弃用。ASMX也已经很长时间没有任何重大升级了。我以前在使用ASXM服务(例如Amadeus)时遇到过反序列化程序的并发问题。
然后,有些人甚至不尊重自己的XSDs,例如Farelogix。他们可能返回枚举值超出范围的值,并说“嗯,XSD仅供信息用途”。WSDL文件明确标记为“不可用于生产”。
不幸的是,没有通用解决方案。以下是一些选项:
  • 如果您要使用.NET Core,则无法使用wsdl.exe和ASMX。您必须切换到完整框架才能使用它们。
  • 为每个服务创建WCF的单独代理。文件大小要小得多,并且避免了像Airport这样的类型之间的冲突,这些类型由多个服务使用,具有轻微的变化或甚至不兼容性。
  • 使用Fiddler或其他工具捕获请求和响应。将其用作创建纯HTTP GET请求的模板。这是一个不太干净的解决方案,但如果您不能信任提供程序的WSDL和XSD,则可能证明更快速,更可靠
警告 发出调用并不意味着您可以与提供商通信。ebXML在SOAP上的主要问题之一是主体是正确的,但包括用于身份验证的标头全部错误。这意味着必须创建身份验证元素
另一个问题是经常滥用身份验证字段,例如使用我们认为是会话令牌的身份验证标头。GDS仍然使用大型机,这些会话令牌通常映射到实际终端会话。
这意味着必须手动创建身份验证标头,而不能依赖WCF生成它们。这也意味着交易是有状态的-必须跟踪用于该预订的哪个会话,在开始新交易之前确保所有先前的交易都已完成等等。

非常感谢,它起作用了。 - Ahmad1334
非常详细而优美的解释。 - PSK
这是我的痛苦在说话。我现在正在与Farelogix合作,刚刚发现他们更改了不同日期退款所返回的信息!即使今天打电话过去。 - Panagiotis Kanavos
我们按照这些步骤进行操作,看起来一切都很顺利。但是当我们尝试实际使用客户端时,出现了“找不到入口点”的错误。有什么想法吗? - BryceBy

10

将WSDL文件下载到本地。然后运行以下命令:

wsdl.exe /verbose /namespace:Air /out:D:\t\ar /protocol:SOAP /language:CS C:\path\to\wsdl\AAResWebServices_1.wsdl

将命名空间更改为您选择的命名空间。

WSDL.exe是您的Windows SDK的一部分:

C:\Program Files (x86)\Microsoft SDKs\Windows

我的文件位于C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin中。

这样生成的类没有任何问题。我测试了这个解决方案。


1
wsdl.exe 用于 ASMX 服务。这些类不是 .NET Core 的一部分。 - Panagiotis Kanavos
@PanagiotisKanavos 我真的没有检查这里“Core”可用/不可用的内容 - 但是想必 svcutil.exe 更可取? - Marc Gravell
1
@MarcGravell 是的,但痛苦在其他地方。 航空公司太大了,不会费心遵循标准。 在我的回答中有解释。 - Panagiotis Kanavos
@MarcGravell 这个问题是一个很好的例子,如果你了解业务,它可能看起来不好,但实际上并不是。 - Panagiotis Kanavos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接