C# 通过WCF运行SOAP API,同时并行运行RESTFul服务

C# 通过WCF运行SOAP API,同时并行运行RESTFul服务,c#,wcf,web-services,rest,soap,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/devi

我有一些SOAP.svc端点当前被命中,但是我需要向我的项目中添加RESTful端点,同时仍然保持旧的端点

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

我正在考虑使用ASP.NET MVC来实现RESTful API,但我不知道如何将此与SOAP/WCF接口并行。我已经读到,这可能与服务路由

我希望事情看起来如何的一个例子:

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

POST website.com/activation/deviceNumber/123(发布其他参数)


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

你基本上需要:

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

[OperationContract]  
[WebGet(UriTemplate = "website.com/activation/deviceNumber/{id}")]
.2。使用webHttpBinding添加另一个服务端点:

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


下面的答案是很好的锅炉板的东西,所以它将有望有助于其他人咨询它,也就是说,我没有试图侮辱任何人的智慧

轻度未经证实的意见: 关于如何做到这一点,您需要咨询很多资源(也有很多废话,而且在这方面也只有很少有用的资源)。不幸的是,在CodeProject上发现了很多不好的信息——但这只是我的观点

首先,我会咨询一些有关C-Sharp Corner的资源,特别是达南杰·库马尔(Dhananjay Kumar)。这里有一个学习曲线(有些事情留给推断),但它是我找到的最好的资源。然而,不管你查阅的资源如何,其他帖子都是正确的,这是通过Windows通信基金会(WCF;或者,“DUB-C-F”)最好的。p> 我对
.config
文件很糟糕(对.Net Framework 4.5之前版本的主要抱怨之一是
.config
文件太大;谷歌“避开
.config
文件”,你会看到很多“东西”)。真的,在深入研究了几个小时之后,它们开始变得有意义了。但是,学习如何使用
.config
文件确实需要一些注意。然而,随着.NET4.5框架的出现,许多情况发生了变化:据我所知,微软开始尽可能地消除繁重的
.config
文件。从
.config
文件中可以执行的所有操作,都可以从代码中执行(从代码中访问它有时可以更好地理解
.config
s)

我自己的问题是: 我需要创建一个
Windows服务
,它在不使用
.config
文件的情况下公开了SOAP和RESTful端点(我的办公室目前出于上述相同的原因不鼓励在那里使用)

no-.config解决方案: 在这里,我将提供一些用于我的服务的代码和一些解释。有些是伪代码。我是在.NET3.5框架中写的。在隔离服务配置时,4.5为您的代码提供了更大的灵活性和精确度

分离接口 很简单,对吧?为SOAP端点设计一个接口(
ISOAP
),为RESTful端点设计另一个接口(
IREST
)。在一个类中实现和定义(即将函数签名赋予主体),我们称之为
DualService
。从接口中分离出来只会在逻辑上帮助我们(并且允许您在以后单独地将它们放置到位,如果需要的话;为什么要牺牲可重用性来浪费好的时间和代码?)

接口定义 注意:这里的所有代码都是用相当“详细”的VB.NET语言编写的。不幸的是,SO对VB注释(或微软老派的
REM
关键字)不是特别满意,所以我使用
/
注释语法。互联网上有更好的C#资源(因此我引用C-Sharp Corner)

肥皂剧

// 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
是时候实施了 真的,我正试图保持这个简短,因为我的代码的内容稍后会出现

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框架中更容易实现

// 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
收尾 因此,这里真正“发生”的是,您正在实例化一个服务类型为
DualService
ServiceHost
——一个实现对RESTful和基于SOAP接口的调用的服务。但是,正如您在代码中所看到的那样,警告是:在添加端点时,您必须指定哪个接口包含哪些公开调用—对于
WebHttpBinding
我们有
IREST
接口
,对于所有SOAP,我们有
ISOAP

我不知道错误处理会是什么样子;但是,从理论上讲,您可以在.NET
中实现一个
函数
,实现两个
接口
的签名(这里,我假设的是
双服务
)。我不确定这能做什么,因为我没有追求它,只是注意到我能做到。但是,如果它真的有效,您可以稍微减少代码。同样,“问题”是SOAP服务抛出的
FaultExceptions

下面是代码(在这种情况下,两个接口签名需要完全相同-请发挥您的想象力):

这是一种公开服务的代码密集的方式。从本质上说,我们接受了answe
// 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
Function DoSomething(ByVal aBluh As TDog) As Boolean Implements IREST.DoSomethingREST, ISOAP.DoSomethingSOAP