并行运行RESTFul服务时通过WCF运行SOAP API

时间:2013-12-30 18:05:16

标签: c# wcf web-services rest soap

我有一些当前被点击的 SOAP .svc 端点,但我需要在保留旧端点的同时将RESTful端点添加到我的项目中。

目前所有内容都通过IIS托管,就像应用程序池中的简单网站一样。

我正在研究使用 ASP.NET MVC 来实现RESTful API,但我不知道我将如何与 SOAP /并行使用它WCF 接口。我已经读过服务路由可以实现这一点吗?

我想要看的东西的一个例子:

  

website.com/base.svc(SOAP信封/方法“使用参数激活”)

  

POST website.com/activation/deviceNumber/123(张贴其他参数)

2 个答案:

答案 0 :(得分:3)

我认为您可能希望使用WCF托管您的REST服务端点。

你基本上需要:

0.1。展开“web方法”属性以包括:

[OperationContract]  
[WebGet(UriTemplate = "website.com/activation/deviceNumber/{id}")]

0.2。使用webHttpBinding添加另一个服务端点:

<service name="BaseService">
    <endpoint address="soap" binding="basicHttpBinding" ...
    <endpoint address="xml" binding="webHttpBinding" ...

以下链接提供了一个很好的概述:
http://www.codeproject.com/Articles/571813/A-Beginners-Tutorial-on-Creating-WCF-REST-Services

答案 1 :(得分:0)

以下答案非常简单,所以希望对其他人有所帮助,即我不会侮辱任何人的情报。

轻度未经证实的意见:

您需要咨询一些资源,了解如何执行此操作(此外,还有很多垃圾,只有极少有用的资源)。不幸的是,在CodeProject上发现了很多不好的信息 - 但这只是我的看法。

我首先要咨询C-Sharp Corner的一些资源,特别是Dhananjay Kumar的this article。有一点学习曲线(有些事情需要推断),但它是我找到的最佳资源。但是,无论您咨询哪种资源,另一篇文章都是正确的,这一点最好通过Windows Communication Foundation(WCF;或者&#34; dub-C-F&#34;)完成。

我对.config个文件感到非常糟糕(关于.Net Framework 4.5之前的一个主要抱怨是大.config个文件; Google&#34;避免.config文件&#34;你会看到很多&#39;)。真的,在钻研了几个小时后,它们开始变得有意义了。但是,学习如何使用.config文件确实需要一些关注。然而,在.Net 4.5 Framework中,很多都发生了变化:从我的阅读中,微软开始尽可能地消除繁琐的.config文件。您可以从.config文件中执行的所有操作,您可以从代码中执行(并从代码中接近它有时可以更好地理解.config s)。

我自己的问题:

我需要创建一个Windows Service来暴露SOAP和RESTful端点而不使用 .config 文件(我的办公室目前不鼓励使用出于同样的原因 - 时间 - 上面提到的)。

一个no-.config解决方案:

我将提供一些代码,在这里,我用于我的服务和一些解释。有些将是伪代码。我在.Net 3.5 Framework中写了这个。在隔离服务配置时,4.5可为您的代码提供更高的灵活性和精确度。

分离界面

够简单吧?为SOAP端点(ISOAP)设计一个接口,为RESTful端点设计另一个接口(IREST)。在一个类中实现和定义(即赋予函数签名的主体),让它称之为DualService。分离出接口实际上什么也没做什么,只能在逻辑上帮助我们(并允许你将它们分开放置,如果需要,以后;为什么通过牺牲可重用性来浪费好时间和代码?)。

接口定义

注意:这里的所有代码都是用#34; verbose&#34; VB.NET语言。不幸的是,SO并没有特别好好利用VB评论(或微软的老派REM关键字),所以我使用//评论语法。互联网上有更好的资源用于C#的东西(因此我引用了C-Sharp Corner)

<强> SOAP

// Decorate each interface with the Service Contract decoration:
<ServiceContract()> _
Public Interface ISOAP 

// For SOAP, each exposed operation gets the Operation Contract definition:
<OperationContract()> _
Function DoSomethingSOAP() As Boolean

End Interface

BOOM!我们已经获得了SOAP服务接口。 SOAP only 使用XML进行序列化 - 根据MSDN改进了它的互操作性。与REST不同,SOAP可以配置为使用各种协议进行数据交换(我们只使用HTTP)。

<强> REST

REST - 在界面设计中 - 实际上与SOAP不同。真正的区别在于两件事:(1)数据是如何序列化的; (2)指定端点 - 或者,&#34; true&#34; REST-speak,&#34;资源 - 被访问(两者都是 - 而且&#39;哦更多&#39; - 我相信你已经熟悉了;如果没有,这里有适度的帮助resource

// Again, we decorate with the Service Contract decoration:
<ServiceContract()> _ 
Public Interface IREST

// Here is/are the above mentioned difference(s)
// Some resources will tell you REST doesn't have a default communication
// format. That's non-sense. In .NET it's XML (hence, it ain't specified, below):
<OperationContract()> _
<WebInvoke(UriTemplate:="/POSTSOMETHING", Method:="POST")> _
Function DoSomethingREST(ByVal anObject As aCustomTypePerhaps) As Boolean

实施时间

真的,我试图保持这个简短的内容,因为我的代码的内容会在以后出现。

Public Class DualService
Implements ISOAP, IRest

Function DoSomethingSOAP() As Boolean Implements ISOAP.DoSomethingSOAP
    Dim Result As Boolean = True
        // Figure out what to do with errors
    Return Result
End Function

Function DoSomethingREST(ByVal anObject As CustomTypePerhaps) As Boolean Implements IREST.DoSomethingREST
    Dim Result As Boolean = True
        // Don't need to do anything with errors; HTTP errors will do that for you
    Return Result
End Result

现在怎么办?:公开服务

注意:同样,这一切都是从代码中完成的。其中一些可能最终有点伪y。此外,为了所有好的事情,请更好地组织您遇到的事情,

如上所述,下面是多肉的。不用担心。它非常内容,因为我希望更合理地组织它,希望通话和配置更有意义。同样,这可以从.config文件配置,并且更容易使用4.5 Framework。

// Instantiate an accessible ServiceHost-type variable. Notice, the GetType() call
// Each subsequent call sets the service up for SOAP and REST (WebHTTPBinding), and
// adds various behaviors to the service, including metadata behavior:
Private Sub ConfigureServiceHost(ByVal aHostName As String, ByVal aPort As Integer)
    Dim URL As String = String.Format("http://{0}:{1}/Service/", aHostName, aPort)
    _ServiceHost = New ServiceHost(GetType(DualService), New Uri(URL))

    AddWebHTTPBinding()
    AddSOAPBinding()
    AddServiceBehavior()

End Sub

// Here, again, notice the call to GetType() - another reason for separating our interfaces
Private Sub AddWebHTTPBinding()
    Dim _WebHTTPBinding As New WebHttpBinding
    Dim EndPoint As ServiceEndpoint
    Dim _WebHTTPBehavior As New WebHttpBehavior

    _WebHTTPBinding.MaxReceivedMessageSize = Int32.MaxValue
    _WebHTTPBinding.SendTimeout = New System.TimeSpan(0, 5, 0)
    _WebHTTPBinding.ReceiveTimeout = New System.TimeSpan(0, 5, 0)

    // If these calls are foreign, look them up in MSDN. Here, you are adding an EndPoint
    // to _ServiceHost of type IREST, with the specified behavior, at location "/WebService"
    EndPoint = _ServiceHost.AddServiceEndpoint(GetType(IREST), _WebHTTPBinding, "WebService")
    EndPoint.Behaviors.Add(_WebHTTPBehavior)

End Sub

// Let's set up SOAP:
Private Sub AddSOAPBinding()
    Dim _BasicHTTPBinding As New BasicHttpBinding
    Dim EndPoint As ServiceEndpoint

    // See the comment for the similar call in the AddWebHttpBinding call:
    EndPoint = _ServiceHost.AddServiceEndpoint(GetType(ISOAP), _BasicHTTPBinding, "SOAP")

End Sub

// Let's get our metadata on, y'all!
// This just enables people developing clients to be able to hit our service, looking for WSDL
// and HELP information. 
Private Sub AddServiceBehavior()
    Dim _ServiceMetadataBehavior As ServiceMetadataBehavior = New ServiceMetadataBehavior

    _ServiceMetadataBehavior.HttpGetEnabled = True
    _ServiceHost.Description.Behaviors.Add(_ServiceMetadataBehavior)

End Sub

总结

那么,真正正在发生的事情&#39;这是您正在实例化ServiceHost,其服务类型为DualService - 一种服务,它实现对基于REST和SOAP的接口的调用。但是,正如您在代码中所看到的,警告是 - 在添加端点时,您必须指定哪个接口包含哪些公开的调用 - 对于WebHttpBinding我们已经IREST {{1对于SOAP而言,我们已经获得了Interface

我不知道错误处理会是什么样的;但是,从理论上讲,你可以在.NET ISOAP两个Function签名中使用一个Implements(这里,我假设关于Interface) 。我不确定这会做什么 - 因为我并没有注意到我能做到这一点。但是,如果真的有效,你可以减少你的代码。再次,&#34;问题&#34;将由SOAP服务引发DualService

这里是代码(在这种情况下,两个界面签名都需要相同 - 使用你的想象力):

FaultExceptions

这是一种暴露服务的代码密集型方式。从本质上讲,接受的答案可以完成以下Function DoSomething(ByVal aBluh As TDog) As Boolean Implements IREST.DoSomethingREST, ISOAP.DoSomethingSOAP 文件中的大部分内容(我相信.config文件非常优雅)。

另外,作为最后一点,对于.config,我暴露了一个POST(IREST)调用,因为这些是一些似乎没有人喜欢用作示例的棘手调用。这是我在示例中稍微更改了签名的唯一原因。