C# 通过WCF运行SOAP API,同时并行运行RESTFul服务
我有一些SOAP.svc端点当前被命中,但是我需要向我的项目中添加RESTful端点,同时仍然保持旧的端点 目前所有内容都是通过IIS托管的,就像应用程序池中的一个简单网站一样 我正在考虑使用ASP.NET MVC来实现RESTful API,但我不知道如何将此与SOAP/WCF接口并行。我已经读到,这可能与服务路由 我希望事情看起来如何的一个例子: website.com/base.svc(带参数的SOAP信封/方法“激活”) POST website.com/activation/deviceNumber/123(发布其他参数)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
我认为您可能希望使用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