在类库项目中创建 Web 服务






4.69/5 (20投票s)
2007年11月24日
2分钟阅读

123777
本文解释了如何在类库项目中创建 Web 服务
引言
最近我参与了一个基于插件的系统,该系统的方法之一是允许每个插件(dll)都能够托管 Web 服务。我以前从未听说过这样的任务,我在网上搜索了一下,但没有找到任何相关内容,所以我决定自己思考,幸运的是,我提出了一个相当好的解决方案。
.asmx 的 HTTP 处理程序
我做的第一件事是打开位于 %windir%\Microsoft.NET\Framework\v2.0.50727\CONFIG 的 Web.Config 文件,并查看 <httpHandlers> 内部的以下条目
<add path="*.asmx" verb="*" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="False" />
使用 Reflector,我发现 WebServiceHandlerFactory 构建并返回一个 IHttpHandler 在 IHttpHandlerFactory 接口的 GetHandler 中,这就是我需要知道的全部内容。
创建 WebServiceBase 类
这就是我所做的
我创建了一个新的类库项目,并在该项目中创建了一个名为 WebServiceBase
的类,这个类可以在任何地方,因为它是一个将作为 Web 服务基类的抽象类。该类的定义如下
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Reflection
Public MustInherit Class WebServiceBase
Inherits WebService
Implements IHttpHandlerFactory
Private Shared wshf As New WebServiceHandlerFactory
Private Shared coreGetHandlerMethod As MethodInfo = GetType(WebServiceHandlerFactory).GetMethod("CoreGetHandler", _
BindingFlags.Instance Or BindingFlags.NonPublic)
Public Function GetHandler(ByVal context As System.Web.HttpContext, ByVal requestType As String, ByVal url As String, _
ByVal pathTranslated As String) As System.Web.IHttpHandler Implements System.Web.IHttpHandlerFactory.GetHandler
Return DirectCast(coreGetHandlerMethod.Invoke(wshf, New Object() {Me.GetType, context, context.Request, context.Response}), IHttpHandler)
End Function
Public Sub ReleaseHandler(ByVal handler As System.Web.IHttpHandler) Implements System.Web.IHttpHandlerFactory.ReleaseHandler
End Sub
End Class
注意反射的技巧来调用 WebServiceHandlerFactory 的 CoreGetHandler 方法,这是必需的,因为该方法被声明为 Friend,并且该方法实际上创建了 IHttpHandler 实例。
快完成了!现在您所要做的就是创建 Web 服务,这些服务将是从这个类继承的类,所以这里有一个例子
Imports System.Web.Services
<WebService(Namespace:="http://tempuri2.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
Public Class WSTest
Inherits WebServiceBase
<WebMethod()> _
Public Function HelloWorld() As String
Return "Hello World"
End Function
End Class
请记住,以上所有内容都在一个类库中,因此请编译此项目,创建一个新的网站,并将此项目添加为引用。
我将此类库项目命名为 WSLibrary,并且由于 WSTest
仅仅是一个 HttpHandler
,您应该为创建的每个 Web 服务向您的 web.config 添加一个新条目,在上面的示例中,我添加了
<httpHandlers>
<add path="WSTest.asmx" verb="*" type="WSLibrary.WSTest" validate="false"/>
</httpHandlers>
现在,每次请求 WSTest.asmx 时,都将由 WSLibrary 项目处理。它可以很容易地更改以适应您的需求。
结论
这种方法对于我正在进行的项目非常有效。我相信可以做更多的事情来使它更好,例如,您可以找到一种方法,使 httpHandlers
中只需要一个条目即可处理您拥有的尽可能多的 Web 服务。