WebAPI 是否支持 SOAP?我正在尝试在 MVC4 中编写一个 SOAP 服务器,虽然我可以在 WCF 中做到这一点,但似乎 WebAPI 正在取代它,但我看不到在其中使用 SOAP 的方法,只是使用 REST 样式接口的 JSON / XML。
6 回答
引用 Scott Guthrie 的话:过去几年 Web API 的兴起——服务通过普通的 HTTP 而不是通过更正式的服务合同(如 SOAP 或 WS*)公开。
所以我会说不。
您应该考虑查看ServiceStack,它允许您的相同服务支持 REST + SOAP API,尽管由于 SOAP 仅适用于HTTP POST,因此它有一些限制
添加 ServiceStack 参考
作为 SOAP 的替代方案,ServiceStack 提供了 WCF 的Add Service Reference的更好替代方案,它可以使用内置于ServiceStackVS的Add ServiceStack Reference功能从 URL 生成类型化 API 。
相对于 WCF 的优势
- Simple使用一个小的 T4 模板来保存生成的 POCO 类型。更新就像重新运行 T4 模板一样简单
- Versatile Clean DTO 适用于所有 JSON、XML、JSV、MsgPack 和 ProtoBuf通用服务客户端
- 可重用生成的 DTO 不与任何端点或格式耦合。默认值既是部分的又是虚拟的,以最大限度地重复使用
- 与 RPC 服务相比,基于弹性消息传递的服务具有许多优势
- 灵活的 DTO 生成是可定制的,服务器和客户端可以覆盖内置默认值
- 在 DTO 上注释的集成丰富服务元数据,外部访问时排除内部服务
WebAPI 和 WCF 都促进 RPC 方法签名
有趣的是,尽管WebAPI ApiController 方法在使用 C# RPC 方法创建和定义聊天 Web 服务时采用了与 WCF相同的RPC 方法,但它们仍然无法支持同一公司制定的自己的 SOAP 标准。
ServiceStack 支持具有相同服务的 REST、SOAP、HTML 和 MQ 端点
这是对 ServiceStack 的基于消息的设计的证明,它提供了许多优点,尽管同一服务能够支持多个端点和格式,包括 REST、SOAP 和 MQ 端点,以及生成服务器端或客户端 HTML 网站,如果你需要它。这是一个丰富的Northwind 数据库编辑器的示例,因为它是使用 ServiceStack 构建的,它自动启用了一个类型化的 REST API,该 API 能够被丰富的本地桌面客户端、移动应用程序和单页应用程序调用。
SOAP 对于远程服务来说仍然是一个糟糕的选择
尽管出于互操作性、可访问性和向后兼容性的原因支持 SOAP,但我们不建议将其用于构建 Web 服务平台,因为它不必要地复杂、脆弱、缓慢和冗长,并且有更好的替代方案可供使用。我在 InfoQ 的采访中更详细地解释了这一点。
WEB API 是微软对基于 REST 的 API 的回应。如果您想要 SOAP,请使用 WCF。
WebApi 确实不支持开箱即用的 SOAP。但它是一个非常灵活的框架,您可以“调整”它来处理 SOAP:没有什么可以阻止您手动解析接收到的 SOAP 消息(它们毕竟是纯 XML)并手动将响应生成为 XML 字符串,然后将它们与适当的内容类型标头(您甚至可以为此编写自己的内容格式化程序)。
根据您的需求和您现有的代码库,这可能值得付出努力,或者您可能希望使用更符合 SOAP 的技术,例如 WCF 或已经提到的ServiceStack框架。
您可能想查看ServiceStack,它应该在一个界面中同时支持 SOAP 和 REST,没有任何麻烦。它声称比 WebAPI 更适合用于 Web 服务。
我不能声称知道所有关于差异的事情,但他们声称的问题是 Web API 方法固有的问题,我可以从经验中说是真实的 - API 演变(在实际项目中不可避免)在 Web api 中非常棘手。当然,web api 不支持 SOAP。
它不像 Wed API 支持 SOAP,但由于 SOAP 只是一个使用 XML 的标准并且它传播 HTTP,您可以使用 Web API 公开 POST 服务来读取 XML 并使用 XPath 找到您需要的节点,然后反序列化节点到对象。
首先,您需要向 ConfigureServices 添加 XML 支持
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddXmlSerializerFormatters();
}
然后在您的控制器中,您只需要添加一个接收 XMLDocument 的方法并使用 XPath 搜索您感兴趣的节点(基本上删除肥皂信封、标题、正文),然后您可以反序列化该对象。在我的例子中,我使用 WSDL 添加服务引用,然后反序列化对象。
[HttpPost("reservationxml")]
public void CreateReservationFromTSW(XmlDocument soapCreateReservationRq)
{
XmlNamespaceManager nsmgr = new XmlNamespaceManager(soapCreateReservationRq.NameTable);
nsmgr.AddNamespace("r", "http://soa.company.com/ReservationEnt");
nsmgr.AddNamespace("s", "http://www.w3.org/2003/05/soap-envelope");
XmlNodeList xmlNodeList = soapCreateReservationRq.SelectNodes("s:Envelope/s:Body/r:CreateReservationRq",nsmgr);
XmlNode xmlnode = xmlNodeList[0];
XmlSerializer serial = new XmlSerializer(typeof(ServiceReference1.CreateReservationRqType));
ServiceReference1.CreateReservationRqType rq = (ServiceReference1.CreateReservationRqType)serial.Deserialize(new XmlNodeReader(xmlnode));
}
正如您在下图中看到的那样,尝试使用您的服务的服务使用带有 Accept-Encoding: gzip 的请求方法 POST。这就是为什么您可以公开可用于 SOAP 服务的 Web API。