ASP.NET WebAPI + Soap

30

WebAPI支持SOAP吗?我正在尝试在MVC4中编写一个SOAP服务器,虽然我可以在WCF中完成,但似乎WebAPI正在替换它,但我还没有找到使用SOAP的方法,目前只看到了使用REST风格接口的JSON / XML。


如果同时拥有两者很重要,您可以始终使用WCF REST 4.0模板,并提供POX / JSON服务端点,还可以在其中混合自定义SOAP端点以进行RPC。 - leon.io
6个回答

20

引用Scott Guthrie的话:过去几年中,我们见证了Web API的崛起 - 这些API是通过普通HTTP公开的服务,而不是通过更正式的服务协议(如SOAP或WS *)。

所以我会说不。


5
有点遗憾 :( 虽然这是事实,但并不是每个人都已经转向使用SOAP,因此互操作性仍需要SOAP。 - John Mitchell
使用REST API并不意味着您不能拥有正式的合同 - 例如Swagger。 - Ondrej Svejdar
@OndrejSvejdar 确实如此,但如果正式合同没有为最终用户带来任何价值,我就不会费心。 - Sandman

18

我建议您考虑使用ServiceStack,它可以支持REST和SOAP API。不过需要注意的是,由于SOAP只能通过HTTP POST工作,因此有一些限制。

Add ServiceStack Reference

与SOAP相比,ServiceStack提供了更好的替代方案,可以使用ServiceStackVS内置的Add ServiceStack Reference功能从URL生成类型化API,这是WCF的Add Service Reference所没有的。

优势

  • 简单 使用小型T4模板保存生成的POCO类型。更新只需重新运行T4模板即可。
  • 通用 干净的DTO适用于所有JSON、XML、JSV、MsgPack和ProtoBuf 通用服务客户端
  • 可重用 生成的DTO未与任何端点或格式耦合。默认值既是部分的,也是虚拟的,以实现最大程度的重用。
  • 弹性 基于消息传递的服务提供了许多优于RPC服务的优势。
  • 灵活 DTO生成可定制,服务器和客户端可以覆盖内置默认值。
  • 集成 丰富的服务元数据在DTO上进行注释,内部服务在外部访问时被排除。

WebAPI和WCF都推广RPC方法签名

有趣的是,尽管WebAPI ApiController方法采用了与WCF相同的RPC方法来创建和定义聊天式Web服务,但它们仍然无法支持由同一公司制定的自己的SOAP标准。
ServiceStack支持使用相同服务的REST、SOAP、HTML和MQ终端点。

这是对ServiceStack的基于消息的设计的证明,它提供了众多优势,包括能够支持同一服务的多个终端和格式,如REST、SOAP和MQ终端,以及生成服务器端或客户端HTML网站(如果需要的话)。以下是一个丰富的Northwind数据库编辑器的示例,因为它是使用ServiceStack构建的,所以自动启用了一个类型化的REST API,可以通过原生桌面客户端、移动应用程序和单页应用程序进行调用。

SOAP仍然是远程服务的不佳选择

尽管出于互操作性、可访问性和向后兼容性的考虑而支持SOAP,但我们不建议将其用于构建Web服务平台,因为它过于复杂、脆弱、缓慢和繁琐,有更好的替代方案可供使用。在我的InfoQ采访中会详细解释

ServiceStack 的一个问题是,它的操作返回类型为 System.Object,这使得编译时的类型检查变得困难。 - Jon Davis
@stimpy77 这是完全可选的,您可以在需要时指定具体的返回类型。请注意,我们更喜欢在 IReturn<T> 标记上指定响应类型,以便客户端也能获得类型化的 API。 - mythz
这个“完全可选”的行为在v4中改变了吗,还是一直都是可选的? - Jon Davis
@stimpy77,新API允许这样做,而在v3的原始旧API中不可用,因为它会强制覆盖现有方法。 - mythz

16

Web API 是微软对基于 REST 的 API 的回应。如果您需要 SOAP,请选择 WCF。


7
WebApi默认不支持SOAP,但它是一个相当灵活的框架,您可以“适应”它来处理SOAP:没有任何阻止您手动解析接收到的SOAP消息(它们毕竟是纯XML),并手动生成响应作为XML字符串,然后使用适当的内容类型标头发送它们(您甚至可以编写自己的内容格式化程序来实现此目的)。
根据您的需求和现有代码库,这可能值得一试,或者您可能希望使用更加友好的SOAP技术,例如WCF或已经提到的ServiceStack框架。

1
最近我刚刚这样做了,并创建了自己的SoapMessageFormatter,以便将具有application/soap+xml请求格式的HTTP POSTS导入到专门设计用于解析XML并将其转换为POCO的特殊端点中,以便可以正常处理它。然后结果通过响应进行相同的翻译。 - Garrison Neely
我在这里写了一个关于如何使用ASP MVC接收SOAP请求的答案 - https://stackoverflow.com/questions/27985639/is-it-possible-to-model-bind-a-soap-request-with-mvc/58254951#58254951 - JeeShen Lee

3
你可能想看一下ServiceStack,它应该支持SOAP和REST在一个接口中,而且非常方便。它声称是WebAPI的更好的选择之一。

我不能说我知道所有的区别,但他们声称的WebAPI方法中存在的问题,我可以通过经验证实确实存在-API演化(在真正的项目中不可避免)在Web API中相当棘手。当然,Web API不支持SOAP。


2

虽然Web API不直接支持SOAP,但由于SOAP只是使用XML并通过HTTP传输的标准,您可以使用Web API公开POST服务来读取XML,并使用XPath查找所需节点,然后将节点反序列化为对象。

首先,您需要将XML支持添加到ConfigureServices中。

public void ConfigureServices(IServiceCollection services)
    {

        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddXmlSerializerFormatters();
    }

然后在您的控制器中,您只需要添加一个接收XMLDocument的方法,并使用XPath搜索您感兴趣的节点(基本上删除soap包装、头文件和正文),然后您可以反序列化对象。在我的情况下,我使用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));


    }

正如您在下面的图像中所看到的那样,尝试使用一个请求方法为POST和Accept-Encoding: gzip的服务来消费您的服务。因此,您可以公开一个Web API,用于SOAP服务的消费。 enter image description here

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